Zend_Controller + Smarty3 アプリでデザイナーさんでも静的な汎用ページを増やせるようにする

PHP

たまにはプログラマらしく本職のphpソースでも晒したいと思います。

ZendFramework-logo

ZendFramework1のコントローラーで制御されたアプリは
Zend_Controller_Actionを継承したクラスとAction()を追加していくので
デザイナーが自分でページを追加しようと思うとphpファイルの編集が入るのでハードルが高すぎます。

なのでtplファイルを置いたらそれがページとして認識できるように汎用的なソースを組みます。

ルーターの設定

***.htmlのように擬似静的に振舞うためいろいろやります。

ルーター設定ファイル

ルーター設定に使用できるフォーマットは各種ありますが自分はyamlファイルを使うことが多いです。

routes.yaml

routes:
 page:
  type: Zend_Controller_Router_Route_Regex
  route: (.+)\.html
  defaults:
    controller: page
    action: index
  map:
   1: pagename
  reverse: %s.html

こんな感じで定義しておきます。
(.+)\.htmlの条件のときはPageController.phpindexAction()、パラメータとしてpagenameに.htmlの呼び出したファイル名が渡されます。

Bootstrap.php

Bootstrap.phpにてルーターの設定をしておきます。
ちょっと脱線しますがroutes.yamlの解析は負荷がかなり高いのでZend_Cacheを使って解析結果を保存しておきます。

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    /**
     * ルーター
     *
     */
    protected function _initRouter()
    {
        $router = $this->bootstrap('frontController')->getRouter();

        $frontendOptions = array(
            'master_file' => APPLICATION_PATH . '/***/routes.yaml',//上記yamlファイルのパス
            'automatic_serialization' => true,
            'ignore_user_abort' => true
        );

        $backendOptions = array(
            'cache_dir' => APPLICATION_PATH . '/temporary/cache/'
        );

        $cache = Zend_Cache::factory('File', 'File', $frontendOptions, $backendOptions);

        if (($config = $cache->load('routes')) === false) {
            $config = new Zend_Config_Yaml( $frontendOptions['master_file'] );
            $cache->save($config, 'routes');
        }
        $router->addConfig($config, 'routes');

    }

$frontendOptions['master_file']のファイル更新時間をキャッシュトリガーにしてます。

コントローラー

PageController.php

class PageController extends Zend_Controller_Action
{
    public function indexAction()
    {
        if (!$this->view->templateExists('page/' . $this->_getParam('pagename') . '.tpl')) {
            //404を返す処理
            ...
            return;
        }
        $this->_helper->viewRenderer->setScriptAction( $this->_getParam('pagename') );
    }
}

よーするに、***.htmlと同名の***.tplが存在しなければ404処理をして、
存在してたらsetScriptActionしています。

フォルダ単位や階層処理も含めたい場合は$this->_helper->viewRenderer->setNoController();を使ってビューへルーパーのコントローラー名設定を解除しておきます。

あぁ・・肝心のZendFramewrok+Smartyのロジックが抜けてますね。
この解説は長くなりそうなのでまた今度やります。

テンプレート

***.tpl

{$zf = $this->headTitle()->prepend('ページのタイトル名')}
{$zf = $this->headLink()->appendStylesheet('/style/***.css')}
Hello World!

$thisとはZend_Viewヘルパーをassignしたものです。

コントローラー側ではタイトルタグなどの設定ができないので
テンプレート側にてビューヘルパーメソッドを使ってページタイトルや、読み込みたいスタイルシートファイルなどの設定をしちゃいます。

ビューヘルパー以外の制御をしたいときはmodelなんかをコントローラーでassignしておけばおk。
または、自分がよく使う手は、Smartyのプラグインで必要になる関数をつくっておく。

$thisメソッドの返り値を$zfで取得していますが、ただのダミーです。
取得しないとその場でechoされちゃったので、こうしています。

ルーター名(page)のreverse%s.htmlを設定してあるので
$this->url()を使ってurlを作成することが可能です。

その他

サイトマップやメニューなども制御したいときはZend_Navigationを組み合わせてあげると手動のCMSっぽくできちゃいます。
・・・なんていい加減な説明(汗)

いろいろ省略してるのでコピペでは使えないソースですが、
こんな感じで上手に組んであげれば、静的ページ追加更新作業が楽になるので
デザイナーさんに仕事のパスが・・やりやすくなるといいね(笑)

コメント

タイトルとURLをコピーしました