Smarty-2.26 を Zend Framework の View として使っていた (参考: Zend_View_Interface を使用したテンプレート) けれど、Smarty-3.1.3 にしたら、Smarty API の命名規則が変わったり、細部の挙動が異なっているなどして、そのままでは動かなくなってしまった。
修正のためいろいろ調べていたのだけれど、Zend のドキュメントの例って、あくまでも Zend_View_Interface の使い方の例として Smarty が持ち出されているだけで、Smarty の使い方の例というわけでもないのだ。
でも、Zend 公式に載ってるから、みんなそれをベースに修正して使ってるのだろう。
で、読んでるうちに、ベースの方向性の違いが気になってきて、いろいろと修正を試みていたのだが、
まあ、これでいいんじゃね? ってのができたのでメモしておく。
基本的な使い方は従来のものと同じ。大きな違いは、Zend_View_Interface の implement)でなく、Zend_View_Abstract の extends とし、Zend_View_Abstract で利用できそうな機構はなるべくそのまま利用するようにしているところ。
だから、従来比で Zend 多め、Smarty 少なめの依存度になっている。たとえば、Smarty::template_dir は設定せず、Zend 側のほうで用意してくれる script path (絶対パス) をテンプレートのパスとして使う、など。
ちなみに、Zend も Smarty もぜんぜん使い込んでないので、両者のいろいろな機能に対応していない箇所は多いとは思うが、そういうのはその都度修正して動くようにすればよいので。方向性としてはこんなもんかな、と思っている。
<?php class Zend_View_Smarty extends Zend_View_Abstract { /** * Smarty object * @var Smarty */ protected $_smarty; /** * コンストラクタ * * @param string $tmplPath * @param array $extraParams * @return void */ public function __construct($config = array(), $extraParams = array()) { require_once 'Smarty/Smarty.class.php'; $this->_smarty = new Smarty(); // Smarty::template_dir は設定しない // Smarty::display() には Zend 側で生成したテンプレートの // フルパスを渡すように $this->_script() で制御する // Zend_View_Abstract::__construct() の実行 $config = (null === $config) ? array() : $config; parent::__construct($config); foreach ($extraParams as $key => $value) { switch ($key) { case 'plugins_dir': $dirs = $this->_smarty->$key; array_unshift($dirs, $value); $this->_smarty->$key = $dirs; break; default: $this->_smarty->$key = $value; } } $this->_smarty->assignByRef('view', $this); } /** * テンプレートエンジンオブジェクトを返します * * @return Smarty */ public function getEngine() { return $this->_smarty; } /** * 変数をテンプレートに代入します * * @param string $key 変数名 * @param mixed $val 変数の値 * @return void */ public function __set($key, $val) { $this->_smarty->assign($key, $val); } /** * empty() や isset() のテストが動作するようにします * * @param string $key * @return boolean */ public function __isset($key) { return (null !== $this->_smarty->getTemplateVars($key)); } /** * オブジェクトのプロパティに対して unset() が動作するようにします * * @param string $key * @return void */ public function __unset($key) { $this->_smarty->clearAssign($key); } /** * 変数をテンプレートに代入します * * 指定したキーを指定した値に設定します。あるいは、 * キー => 値 形式の配列で一括設定します * * @see __set() * @param string|array $spec 使用する代入方式 (キー、あるいは キー => 値 の配列) * @param mixed $value (オプション) 名前を指定して代入する場合は、ここで値を指定します * @return void */ public function assign($spec, $value = null) { if (is_array($spec)) { $this->_smarty->assign($spec); return; } $this->_smarty->assign($spec, $value); } /** * Return list of all assigned variables * * Returns all public properties of the object. Reflection is not used * here as testing reflection properties for visibility is buggy. * * @return array */ public function getVars() { return $this->_smarty->getTemplateVars(); } /** * 代入済みのすべての変数を削除します * * Zend_View に {@link assign()} やプロパティ * ({@link __get()}/{@link __set()}) で代入された変数をすべて削除します * * @return void */ public function clearVars() { $this->_smarty->clearAllAssign(); } /** * Finds a view script from the available directories. * * @param string $name The base name of the script. * @return void */ protected function _script($name) { // $name に対するフルパスを取得 $script_path = parent::_script($name); // Smarty::compile_dir 内に置かれるコンパイル済みのテンプレートの // 衝突回避のために Smarty::compile_id にディレクトリ名を設定する $this->_smarty->compile_id = dirname($script_path); return $script_path; } /** * Includes the view script in a scope with only public $this variables. * * @param string The view script to execute. */ protected function _run() { // render() から呼び出される // 出力は Zend 側でバッファされ、フィルタに渡されるので // Smarty::fetch() ではなく Smarty::display() を使用する return $this->_smarty->display(func_get_arg(0)); } }
<?php require_once "ZendViewSmarty.php"; class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initView() { // application.ini から設定を読み出す準備 $options = new Zend_Config($this->getOptions()); // view.view.viewSuffix を取得 $viewSuffix = $options->view->viewSuffix; // view.smarty.* の設定を配列で取得 $extraParams = $options->view->smarty->toArray(); $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer'); $savedViewSuffix = $viewRenderer->getViewSuffix(); // 初期設定された Smarty オブジェクトを保持する // Zend_View_Smarty オブジェクトのインスタンスを作成 // 1番目の引数は Zend_View_Abstract に渡す設定内容を表す $view = new Zend_View_Smarty(null, $extraParams); $viewRenderer->setView($view) ->setViewSuffix($viewSuffix); } }
application.ini の関連するところ
[production] (略) view.viewSuffix = "tpl" view.smarty.compile_dir = APPLICATION_PATH "/../../smarty/templates_c" view.smarty.plugins_dir = APPLICATION_PATH "/../../smarty/plugins" (略)