Zend_Controllerを使ったWebアプリケーションのテンプレートエンジンにSmartyを使用してみます。
Zend Framework:Hello Worldを表示してみる」のように"Hello World"を表示します。

ディレクトリ構成

ディレクトリ構成は、だいたい次のようにしています。

BASEDIR/
    html/
        .htaccess
        index.php
    lib
        ZendFramework
        ZendFramework-1.0.1/
    webapp/
        modules/
            default/
                controllers/
                templates/
        temporary
            cache
            templates_c

BASEDIRは、ドキュメントルートの一個上のディレクトリです。
htmlは、ドキュメントルートです。
lib/ZendFrameworkは、lib/ZendFramework-1.0.1へのシンボリックリンクにしています。
lib/smartyは、lib/Smarty-2.6.18/libsへのシンボリックリンクにしています。

Smartyのインストール

Smartyは、Smarty : Template Engineからダウンロードできます。

例:

$ cd BASEDIR/lib
$ tar xvzf Smarty-2.6.18.tar.gz
$ ln -s Smarty-2.6.18/libs smarty
escape修飾子

サンプルのテンプレートファイルでは、escape修飾子の引数に何も指定していません。
僕は、smartyに付属のmodifier.escape.phpファイルを次のように、$char_set引数のデフォルト値をUTF-8に変更しています。

Smarty-2.6.18/libs/plugins/modifier.escape.php
PHP:
  1. function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'UTF-8')
  2. {
  3. // 略
  4. }

ディレクトリに書き込み権限を追加

次のディレクトリにapacheが書き込みできるようにします。

  • BASEDIR/webapp/temporary/cache
  • BASEDIR/webapp/temporary/templates_c

例:

$ chmod 777 BASEDIR/webapp/temporary/cache
$ chmod 777 BASEDIR/webapp/temporary/templates_c

Smarty用のViewクラス

Zend_View_Interfaceを継承して、Zend_View互換のSmartyテンプレートエンジンを使用するViewクラスを作成します。
Zend_View_Interface を使用したテンプレートにあるサンプルを元にします。
オリジナルのままではエラーになるので、少し変更しています。
私の間違いです。エラーにはなりませんので、訂正いたします(2007/11/16)。

BASEDIR/webapp04/lib/Tz/View/Smarty.php
PHP:
  1. class Tz_View_Smarty implements Zend_View_Interface
  2. {
  3.   protected $_smarty;
  4.  
  5.   public function __construct($tmplPath = null, $extraParams = array())
  6.   {
  7.     $this->_smarty = new Smarty;
  8.  
  9.     if (null !== $tmplPath) {
  10.       $this->setScriptPath($tmplPath);
  11.     }
  12.  
  13.     foreach ($extraParams as $key => $value) {
  14.       $this->_smarty->$key = $value;
  15.     }
  16.   }
  17.  
  18.   public function getEngine()
  19.   {
  20.     return $this->_smarty;
  21.   }
  22.  
  23.   public function setScriptPath($path)
  24.   {
  25.     if (is_readable($path)) {
  26.       $this->_smarty->template_dir = $path;
  27.       return;
  28.     }
  29.     throw new Exception('無効なパスが指定されました');
  30.   }
  31.  
  32.   public function getScriptPath()
  33.   {
  34.     return $this->_smarty->template_dir;
  35.   }
  36.  
  37.   public function __set($key, $val)
  38.   {
  39.     $this->_smarty->assign($key, $val);
  40.   }
  41.  
  42.   public function __get($key)
  43.   {
  44.     return $this->_smarty->get_template_vars($key);
  45.   }
  46.  
  47.   public function __isset($key)
  48.   {
  49.     return (null !== $this->_smarty->get_template_vars($key));
  50.   }
  51.  
  52.   public function __unset($key)
  53.   {
  54.     $this->_smarty->clear_assign($key);
  55.   }
  56.  
  57.   public function assign($spec, $value = null)
  58.   {
  59.     if (is_array($spec)) {
  60.       $this->_smarty->assign($spec);
  61.       return;
  62.     }
  63.  
  64.     $this->_smarty->assign($spec, $value);
  65.   }
  66.  
  67.   public function assignByRef(&$spec, &$value = null)
  68.   {
  69.     if (is_array($spec)) {
  70.       $this->_smarty->assign_by_ref($spec);
  71.       return;
  72.     }
  73.  
  74.     $this->_smarty->assign_by_ref($spec, $value);
  75.   }
  76.  
  77.   public function clearVars()
  78.   {
  79.     $this->_smarty->clear_all_assign();
  80.   }
  81.  
  82.   public function render($name)
  83.   {
  84.     return $this->_smarty->fetch($name);
  85.   }
  86.  
  87.   public function getScriptPaths()
  88.   {
  89.     return array($this->_smarty->template_dir);
  90.   }
  91.  
  92.   public function setBasePath($path, $classPrefix = 'Zend_View')
  93.   {
  94.  
  95.   }
  96.  
  97.   public function addBasePath($string, $classPrefix = 'Zend_View')
  98.   {
  99.  
  100.   }
  101. }

ViewRendererアクションヘルパーの初期化

ViewRendererを利用して、自動的にテンプレートファイルを選択して、レンダリングするようにします。
ViewRendererアクションヘルパーに、Smartyテンプレートエンジンを使用するViewオブジェクトを登録します。
また、ViewRendererアクションヘルパーのsetViewSuffixメソッドでテンプレートファイルの拡張子がhtmlになるように指定しています。

BASEDIR/webapp04/bootstrap.php
PHP:
  1. function setup_view_smarty($registry)
  2. {
  3.   $webapp_dir = $registry['webappDir'];
  4.   $config = $registry['config'];
  5.   require_once $webapp_dir . '/lib/Tz/View/Smarty.php';
  6.   $smarty_config = $config->smarty->toArray();
  7.   $smarty_config['cache_dir'] = $webapp_dir . '/temporary/cache/';
  8.   $smarty_config['compile_dir'] = $webapp_dir . '/temporary/templates_c/';
  9.   if (!is_dir($smarty_config['cache_dir']) || !is_writable($smarty_config['cache_dir'])) {
  10.     die('smartyキャッシュディレクトリに書き込みできません。');
  11.   }
  12.   if (!is_dir($smarty_config['compile_dir']) || !is_writable($smarty_config['compile_dir'])) {
  13.     die('smartyコンパイルディレクトリに書き込みできません。');
  14.   }
  15.   $default_tpl_dir = null;// テンプレートディレクトリの指定、Tz_Controller_Action::init()で行う
  16.   $view = new Tz_View_Smarty($default_tpl_dir,$smarty_config);
  17.  
  18.   // ViewRendererヘルパーを使用する
  19.   $vr = new Zend_Controller_Action_Helper_ViewRenderer();
  20.   $vr->setView($view);
  21.   $vr->setViewSuffix('html');
  22.   Zend_Controller_Action_HelperBroker::addHelper($vr);
  23. }

テンプレートファイルの配置場所

テンプレートファイルは、コントローラディレクトリを配置したディレクトリ内のtemplatesディレクトリ以下に置くことにします。
このディレクトリがsmartyのテンプレートディレクトリとなるようにします。
例えば、BASEDIR/webapp/modules/default/templatesがテンプレートディレクトリになります。

テンプレートディレクトリは、アクションコントローラのinit()メソッドが起動されたときに設定することにします。

BASEDIR/webapp04/lib/Tz/Controller/Action.php
PHP:
  1. //
  2.     $request = $this->getRequest();
  3.  
  4.     $module  = $request->getModuleName();
  5.     $controller  = $request->getControllerName();
  6.     $action  = $request->getActionName();
  7.  
  8.     $dirs    = $this->getFrontController()->getControllerDirectory();
  9.     if (empty($module) || !isset($dirs[$module])) {
  10.       $module = 'default';
  11.     }
  12.     $templates_dir = dirname($dirs[$module]) . '/templates';
  13.     if (!is_dir($templates_dir)) {
  14.       throw new Exception('テンプレートディレクトリがありません。');
  15.     }
  16.     $this->view->setScriptPath($templates_dir);
  17.  
  18.     $smarty = $this->view->getEngine();
  19.     $smarty->compile_id = $module . '_' . $action . '_' . $controller;

テンプレートファイルの命名規則

テンプレートファイルは、テンプレートディレクトリ内に':controller/:action.:suffix'という規則で配置します。
:controllerはコントローラ名、:actionはアクション名です。
:suffixは、上記「ViewRendererアクションヘルパーの初期化」でhtmlにしています。

例えば、defaultモジュールのindexコントローラのindexアクションが使用するテンプレートファイルは、次の場所になります。

BASEDIR/webapp04/modules/default/templates/index/index.html

dbErrorのようにアクション名に大文字が含まれる場合も、テンプレートファイル名は、すべて小文字となります。

サンプルダウンロード

ダウンロードページにアーカイブしたファイルを置きました。

Tags: ,

コメント / トラックバック 5件

  1. Satoru Yoshida より:

    こんにちは。ゼンドジャパンの吉田と申します。
    内容を拝見していましたら、Smarty用のViewクラスの項目で、「オリジナルのままではエラーになるので、少し変更しています」とありました。

    これは getScriptPaths()の返り値がInterfaceではarrayと定義されているのにプログラマ向けリファレンスガイドではstringを返すようになっていることをおっしゃられていますでしょうか?

    もし覚えていらっしゃいましたらお返事いただけますと幸いです。

  2. trek より:

    はじめまして。

    > これは getScriptPaths()の返り値がInterfaceではarrayと定義されているのにプログラマ向けリファレンスガイドではstringを返すようになっていることをおっしゃられていますでしょうか?

    はい。その通りです。

    エラーという表現は、間違いでした。
    先ほど試しましたところ、Warningでした。
    Warning: Invalid argument supplied for foreach() in
    (略)Zend/Controller/Action/Helper/ViewRenderer.php on line 322

    失礼いたしました。
    訂正いたします。

  3. Satoru Yoshida より:

    お返事ありがとうございます。
    ViewRendererでのWaringが出ている旨英文でレポートしておきます

  4. Heavens hell より:

    [PHP][Zend Framework]Zend_Gdat…

    Zend_GdataでYoutubeの検索を作ってみた。 わずかなコードで作れてしまった。 ※ほとんどオフィシャルのドキュメントに書いてあることだけど・・。 Zend (more…)

  5. [...] Zend Framework:テンプレートエンジンをSmartyにする [...]

コメントをどうぞ