Zend FrameworkはデフォルトではZend_Viewというテンプレートエンジンを使用します。(正確に言うと素のPHPに足りない便利関数集といった感じ。)
SmartyやTwigといったテンプレートエンジンを連携させる場合など、Zend_View以外を使いたい場合のやり方をまとめてみます。
拡張方法の選択
Zend Frameworkは拡張方法がたくさん用意されているフレームワークです。 まずはどう拡張するのかを検討 します。
Viewヘルパーをまず検討
単純な機能拡張であれば、Viewヘルパーを作れないか検討しましょう。要は「関数が足りないので増やしたい」、という場合です。
http://framework.zend.com/manual/ja/zend.view.helpers.html
Viewヘルパーはこのまとめでは扱いません。標準で付属するViewヘルパーが充分高機能なので、標準のViewヘルパーだけで何とかなることが多いでしょう。ヘルパーを作る前に「既に標準でできる内容でないか?」調べたほうがいいです。
ちなみにViewヘルパーを推奨するのは、「継承しなくて済むから」です。Viewクラスの書き換えより簡単に作れますし、拡張性も犠牲になりません。
Viewクラスを直接拡張する
以降は「 Zend_Viewを使いたくない 」「 Zend_Viewの挙動を差し替えたい 」というような場合のやり方です。これらのケースではViewクラスを直接拡張しなくてはなりません。
Zend Frameworkで使うためのViewクラスの条件は、「 Zend_View_Interfaceをimplementsしていること 」だけです。ただし、インターフェースには実装コードは全く書かれていないため、Interfaceから作ると面倒かもしれません。
Zend Frameworkには Zend_View_Abstractという、すでにZend_View_Interfaceをimplementsしているクラスがあり、これは必須メソッドが揃っています。単純なメソッド追加であればこれを使うのも手です。
- Zend_View_Interface をimplementsして、必須メソッドをすべて書く
- Zend_View_Abstract をextendsして、最低限だけ上書きする
- Zend_View をextendsして、最低限だけ上書きする
上に行くほど書くコードは多くなりますが、下に行くほどZend_Viewの複雑な実装を引き継ぐことになります。
ちなみにZend_View_AbstractとZend_Viewの差はごくわずかです。具体的にはソースコードを読みましょう。
「Zend_Viewは全く使いたくない! Twigさえあれば十分だ」ということなら、Zend_View_Interfaceから書いていくのがいいでしょう。
「Zend_Viewの微妙な点が気に食わない!」なら、Zend_Viewを継承して気に食わない部分だけ上書きすればいいです。
ここではZend_Viewをextendsして、escape()メソッドを上書きしてみます。これはhtmlspecialchars()のラッパー関数なのですが、標準のescape()は拡張性の反面、非効率な書き方をしているので、拡張性を捨ててもっとシンプルな実装に差し替えます。
<?php
class My_View extends Zend_View
{
public function escape($str)
{
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
}
簡単なユニットテストはこんなイメージ。Zend_View_Interfaceのインスタンスだと判定されればOK.
<?php
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance()
->registerNamespace('My');
$view = new My_View;
assert($view instanceof Zend_View_Interface);
Zend Frameworkへの組み込み
さて、先程も言ったとおりZend Frameworkは非常に自由度が高いフレームワークで、様々な構成で作ることができます。
ここでは標準的な構成の場合に使えるものを2つ書きますが、構成が違う場合は使えないケースもあるのでご注意ください。
…標準のViewリソースプラグインがクラスの差し替えに対応していれば、こんなややこしいことをしなくてもいいのですが。。。「new Zend_View()」ってハードコーディングされてるんだよね。。
あ、以降のソースコードではオートローダーのコードは省略します。index.phpの先頭あたりにこんなコードが書いてあるものとします。
<?php
require_once 'Zend/Loader/Autoloader.php';
Zend_Loader_Autoloader::getInstance()->registerNamespace('My');
// ...(略
方法1・Bootstrap.phpで初期化する
通常はZend_Application_Resource_Viewが勝手に起動して、勝手にZend_Viewをインスタンス化します。
しかしBootstrap.phpで_initView()というメソッドを作っておけば、リソースプラグインより優先されます。これを使って手動でViewをインスタンス化することができます。
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initView()
{
$view = new My_View;
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setView($view);
return $view;
}
}
方法2・Resourceプラグインを自作する
個人的にはこちらの方法がおすすめ。Bootstrapにベタ書きする手法だと、アプリを作るごとにコードをコピペすることになるので、再利用性が低くなります。
まず、My_Application_Resource_Viewクラスを作成します。これがいわゆるリソースプラグインです。名前が長いのは諦めましょう。
<?php
class My_Application_Resource_View extends Zend_Application_Resource_View
{
public function getView()
{
if (null === $this->_view) {
$options = $this->getOptions();
if (isset($options['classname'])) {
$class = $options['classname'];
} else {
$class = 'My_View';
}
$this->_view = new $class;
}
return $this->_view;
}
}
このファイルを配置したら、あとはapplication.iniでpluginpathsに追加するだけ。
[production]
;..中略..
pluginpaths.My_Application_Resource = "My/Application/Resource"
;..中略..
これで、Zend_Viewの代わりにMy_Viewが使用されるようになります。。長かったw