WEBサービス創造記

WEBサービスを作ったり保守したりしてる人のメモブログです。

Zend_Layoutでモジュールごとに読み込むレイアウトスクリプトを変更する

      2012/12/17

この記事について

この記事は、下記の記事の手順でZend_Layoutを利用出来るようにした後、さらにモジュールごとに違うレイアウトスクリプトを読み込めるようにするための設定を記したものです。
Zend_LayoutとSmartyの連携

以下の記事を参考にして、ほとんど同じことをやっています。
PetaWeb, ZendFrameworkのapplication.iniと、アクションヘルパでモジュール毎のレイアウトを実装

Zend_Layoutでモジュールごとに読み込むレイアウトスクリプトを変更

1. 設定ファイルにモジュール構成への対応を記述

モジュール構成に対応させるため、application/configs/application.ini に以下の数行を追記します。


resources.frontController.controllerDirectory = APPLICATION_PATH "/modules/default/controllers"
resources.frontController.moduleDirectory     = APPLICATION_PATH "/modules"
resources.modules[] =

これはモジュールのディレクトリがすでに設置されていることを前提としています。
モジュールディレクトリの雛形はzfコマンドで簡単に作成することができます。zfコマンドについては下記の記事をご参照ください。

ZFコマンドの使い方

また、既存のモジュールをアプリケーションのデフォルトモジュールとする場合は下記も必要となります。

resources.frontController.params.prefixDefaultModule = "1"

2. Smartyのテンプレートディレクトリ調整

モジュール構成にともなって、テンプレートを格納するディレクトリのパスも変更になったので、ブートストラップで対応する箇所を修正します。

application/Bootstrap.php(抜粋)
        $view = new Zend_View_Smarty(null,$smarty_config);
        $viewRenderer =
            Zend_Controller_Action_HelperBroker::getStaticHelper("ViewRenderer");

        $viewRenderer->setView($view)
                     ->setViewBasePathSpec($view->_smarty->template_dir)
                     ->setViewScriptPathSpec(APPLICATION_PATH . '/modules/:module/views/scripts/:controller/:action.:suffix')
                     ->setViewScriptPathNoControllerSpec(':action.:suffix')
                     ->setViewSuffix('tpl');

3. 設定ファイルにZend_Layoutの設定を記述

続いてZend_Layoutの設定も application/configs/application.ini に記述します。


default.resources.layout.layoutPath = APPLICATION_PATH "/modules/default/layouts/scripts"
hoge.resources.layout.layoutPath    = APPLICATION_PATH "/modules/hoge/layouts/scripts"
resources.layout.viewSuffix         = "tpl"

緑字でハイライトした箇所がモジュール名です。
ここでモジュールごとに読み込むレイアウトスクリプトの基底パスを設定しています。

4. 独自クラスの設置

参考記事にある独自クラスをそのまま使わせてもらってます。
参考記事は名前空間の設定などをしていますが、ここでは便宜上最低限のことだけ行います。

ただし、この例のディレクトリ構成では、全てのモジュールのSmartyのコンパイルファイルを一箇所にまとめています。
このため、コンパイルファイルのファイル名をユニーク化しないと、モジュール間でコントローラ・アクション名が重複していた場合は、別のモジュールのコンパイルファイルを読み込みに行ったりしてしまいます。
従って、このクラスでSmartyのコンパイルファイルの命名のユニーク化処理も行うようにします。

また、このクラスはパスの通っているlibraryディレクトリに設置します。

library/LayoutLoader.class.php
<?php echo '<?php'; ?>

class LayoutLoader extends Zend_Controller_Action_Helper_Abstract
{
  public function preDispatch()
  {
    $request = $this->getRequest();
    $module     = $this->getRequest()->getModuleName() ;
    $controller = $request->getControllerName();
    $action = $request->getActionName();

    $bootstrap  = $this->getActionController()->getInvokeArg( 'bootstrap' ) ;
    $config     = $bootstrap->getOptions() ;
    if( isset( $config[ $module ][ 'resources' ][ 'layout' ] ) ) {
      $this->getActionController()
           ->getHelper( 'layout' )
           ->setOptions( $config[ $module ][ 'resources' ][ 'layout' ] ) ;
    }

    $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
    $smarty = $viewRenderer->view->getEngine();
    $smarty->compile_id = $module . '_' . $action . '_' . $controller;
  }
}

5. ブートストラップでのLayout初期化

ブートストラップに以下の処理を組み込みます。

application/Bootstrap.php(抜粋)
<?php echo '<?php'; ?>

protected function _initLayoutHelper()
{
    $this->bootstrap('frontController');
    require_once 'LayoutLoader.class.php';
    Zend_Controller_Action_HelperBroker::addHelper( new LayoutLoader() );
}

これでアプリケーションの設定ファイルで指定したレイアウトスクリプトが読み込まれるようになると思います。

 - ZendFramework , , , , , ,