FuelPHP Advent Calendar 2011、8日目です。前日は@tao_s さんのFuelPHPとCodeIgniterでCMS作ってパフォーマンスを比べてみたでした。
今日のテーマは「FuelPHP の view に PHPTAL デザインテンプレートを使う」です。
FuelPHP では、ビュー部分は(初期状態では)素の PHP を用います。テンプレートを使いたい、という場合は、packages/parser/classes/view にあるパーサを利用します。パーサは、dwoo, haml, jade, markdown, mustache, smarty, twig が用意されています。
ん?phptal は無いですね。
無ければ作る (オープンソースの醍醐味)
ということで、PHPTAL デザインテンプレートを使うためパーサを作成しました。
class View_Phptal extends View
{
	protected static $_parser;
	protected function process_file($file_override = false)
	{
		$file = $file_override ?: $this->file_name;
		try
		{
			$parser = static::parser();
			foreach($this->get_data() as $key => $value) { 
				$parser->set($key,$value);
			}
			$parser->setTemplate($file);
			return $parser->execute();
		}
		catch (Exception $e)
		{
			// Delete the output buffer & re-throw the exception
			ob_end_clean();
			throw $e;
		}
	}
	public $extension = 'phptal';
	public static function parser()
	{
		if ( ! empty(static::$_parser))
		{
			return static::$_parser;
		}
		static::$_parser = new PHPTAL(); 
		static::$_parser->setEncoding(Config::get('parser.View_Phptal.encoding', 'UTF-8'));
		static::$_parser->setOutputMode(constant(''.Config::get('parser.View_Phptal.output_mode', 'PHPTAL::XHTML')));
		static::$_parser->setTemplateRepository(Config::get('parser.View_Phptal.template_repository', ''));
		static::$_parser->setPhpCodeDestination(Config::get('parser.View_Phptal.cache_dir', APPPATH.'cache'.DS.'PHPTAL'.DS));
		static::$_parser->setCacheLifetime(Config::get('parser.View_Phptal.cache_lifetime', 0));
		static::$_parser->setForceReparse(Config::get('parser.View_Phptal.encoding', false));
		return static::$_parser;
	}
}
既に Smarty 用のパーサがあったので、そちらを参考に作成しました。get_data() でデータを取ってきて、PHPTAL の set で取り込めば OK です。
setEncoding 等は、packages/parser/config/parser.php で設定できます。
FuelPHP の開発チームに pull request したので、FuelPHP に取り込まれる可能性がありますが、1.1rc 時点では自分で追加する必要があります。 https://github.com/ounziw/PHPTAL-for-FuelPHP からダウンロードできます。
使い方
phptal.phpをpackages/parser/classes/view/に追加bootstrap.phpをpackages/parser/に上書きparser.phpをpackages/parser/config/に上書き- PHPTAL ライブラリを http://phptal.org/ から取得し、
app/vendor/に置く app/config/config.phpの ‘always_load’ ‘packages’ に parser を追加する- PHPTAL のキャッシュ機能を使う場合、
app/cache/PHPTAL/が書込可であることを確認する 
後はアプリケーションでビューを呼び出す時、View_Phptal::forge とすれば(素のビューを使う時は View::forge)、PHPTAL テンプレートを使用できます。なお、テンプレートファイル名の拡張子は、デフォルトでは .phptal です。
HTML エスケープ
FuelPHP は、デフォルトで HTML エスケープを行います。PHPTAL も、デフォルトで HTML エスケープを行います。なので、FuelPHP のエスケープ機能をオフにして使います。
app/config/config.php の auto_filter_output 項目を false にしてください。
やってみる
試しに、@kenji_s さんのFuelPHP のブログチュートリアルのビューを PHPTAL にしてみました。
元のビューはこんな感じです。
<h2 class="first">Listing Posts</h2>
<?php if ($posts): ?>
<table cellspacing="0">
	<tr>
		<th>Title</th>
		<th>Summary</th>
		<th>Body</th>
		<th></th>
	</tr>
	<?php foreach ($posts as $post): ?>	<tr>
		<td><?php echo $post->title; ?></td>
		<td><?php echo $post->summary; ?></td>
		<td><?php echo $post->body; ?></td>
		<td>
			<?php echo Html::anchor('posts/view/'.$post->id, 'View'); ?> |
			<?php echo Html::anchor('posts/edit/'.$post->id, 'Edit'); ?> |
			<?php echo Html::anchor('posts/delete/'.$post->id, 'Delete', array('onclick' => "return confirm('Are you sure?')")); ?>		</td>
	</tr>
	<?php endforeach; ?></table>
<?php else: ?>
<p>No Entries.</p>
<?php endif; ?>
<br />
<?php echo Html::anchor('posts/create', 'Add new Post'); ?>
これを PHPTAL テンプレートにします。
<h2 class="first">Listing Posts</h2>
<table tal:condition="exists:posts" cellspacing="0">
	<tr>
		<th>Title</th>
		<th>Summary</th>
		<th>Body</th>
		<th></th>
	</tr>
	<tr tal:repeat="post posts">
		<td>${post/title}</td>
		<td>${post/summary}</td>
		<td>${post/body}</td>
		<td>
		<a tal:replace="structure php:Html::anchor('posts/view/' . post.id,'View')" >View</a>
		<a tal:replace="structure php:Html::anchor('posts/edit/' . post.id,'Edit')" >Edit</a>
		<a 
		tal:define="js string:return confirm('Are you sure?')"
		tal:content="structure php:Html::anchor('posts/delete/' . post.id,'Delete',array('onclick' => js))" 
		>Delete</a>
		</td>
	</tr>
	</table>
<p tal:condition="not:posts">No Entries.</p>
<br />
<tal:block tal:content="structure php:Html::anchor('posts/create', 'Add new Post')" />

PHPTAL は、テンプレートが XHTML 形式です。このため、テンプレートファイル自体をブラウザでプレビューして確認しやすいです(fuelphp を動かせない環境でも、レイアウト確認できる)。PHPテンプレートエンジンベンチマーク パート2 Smarty vs PHPTAL によると、実行速度は Smarty よりやや劣るらしいです。
明日は @cakephper さんFuelPHPでMongoDBを使う です。
[…] プ文字の働きをします。先日の FuelPHP の view に PHPTAL デザインテンプレートを使う のときに失敗しました。 […]
[…] Related posts:FuelPHP の view に PHPTAL デザインテンプレートを使う […]
[…] 私の書いた記事では、FuelPHP の view に PHPTAL デザインテンプレートを使うについて、変更が予定されています。次の FuelPHP バージョンでは PHPTAL が標準で使用可能になる予定です。「PHPTAL […]
[…] ver1.1 で動かすには、https://ounziw.com/2011/12/08/phptal-fuelphp/ にしたがい、View_Phptal […]