私と私の猫の他は誰でも隠し事を持っている

野良プログラマ発、日々のアウトプット

コンパクトな PHP テンプレートエンジン、Latte を使ってみた

Yet Another PHP Template Engine な話。とある PHP システムを作っていて、動的に与えられるテンプレート構文にデータを適用させて、断片的な HTML コードを生成させたい、という要件がありまして、

  • Twig や Blade だと大袈裟というか、かさばりそうなのでなるだけコンパクトなやつ
  • ちゃんとメンテされてて PHP7 でも安心して使えそうなの
  • コードがモダンで、PHP5.4 未満な残滓が無いと嬉しい

なテンプレートエンジンを探してたら Latte という OSS プロダクトを発見。どうやらこれ、Nette という MVC フレームワークの構成ライブラリですが、単体でも問題なく使えるようです。

Latte - amazing template engine for PHP | Nette Framework

で、上記ページを読みながら評価してみました。インストールは compser いっぱつ。

composer require latte/latte

テスト用にこんなスクリプトを書いてみたです(↓)。

<?php
require 'vendor/autoload.php';

$duos = [
	'Simon & Garfunkel' => ['Paul Simon', 'Art Garfunkel'],
	'Peter & Gordon' => ['Peter Assher', 'Gordon Waller'],
];

$template = '<dl n:foreach="$duos as $name => $duo">
	<dt>{$name}</dt>
	<dd>
		<ul>
			<li n:foreach="$duo as $member">{$member}</li>
		</ul>
	</dd>
</dl>';

$latte = new Latte\Engine;
$latte->setLoader(new Latte\Loaders\StringLoader([
	'main' => $template
]));
$latte->render('main', ['duos' => $duos]);

はい、ちゃんとレンダリングされました(↓)。

<dl>
	<dt>Simon &amp; Garfunkel</dt>
	<dd>
		<ul>
			<li>Paul Simon</li>
			<li>Art Garfunkel</li>
		</ul>
	</dd>
</dl><dl>
	<dt>Peter &amp; Gordon</dt>
	<dd>
		<ul>
			<li>Peter Assher</li>
			<li>Gordon Waller</li>
		</ul>
	</dd>
</dl>

デフォルトで HTML エンティティ変換されてるのがイイですね。テンプレートでおや?と思うのが、Vue.js テンプレートのディレクティブみたいな書き方ができること。これを Latte ではマクロと呼ぶようです。分岐やループは

<?php
$template = '{foreach $duos as $name => $duo}
	<dl>{$name}</dl>
	<dd>
		<ul>
			{foreach $duo as $member}
				<li>{$member}</li>
			{/foreach}
		</ul>
	</dd>
{/foreach}';

のように Twig っぽい書き方もできるのすが、マクロを使うことでよりコンパクトなテンプレートが書けますね。

それから Latte の特色として、コンテキスト・アウェアネス指向な件。要は、レンダリングの際に埋め込み場所に応じたセキュリティ対策が考慮されている、ということらしいです。

<?php
$latte->setLoader(new Latte\Loaders\StringLoader([
	'main' => '<p>param is {$param}</p>
<a href="{$param}">Click Here</a>'
]));
$latte->render('main', ['param' => "localtion.href='http://google.com'"]);

を実行すると、

<p>param is localtion.href='http://google.com'</p>
<a href="">Click Here</a>

となり、p タグ内には展開される文字列が、a タグの href 属性内ではオミットされて、スクリプトインジェクションを抑止できます。どうですか? 自分はカナーリ気に入りました、Latte。