unoh.github.com

PHPテンプレートエンジンTwigをいじってみました

Tue Dec 08 22:50:33 -0800 2009

今年のX'masは一人で高いシャンパンを買って飲もうとおもってるKeitaです。

しばらく、情報収集をさぼっている間に、symfonyの開発元であるSensio Labsから、PHPのテンプレートエンジンTwigが出ていたので、1時間ほど試してみました。

つかってみたよーとか、ここきついとかありましたら、コメントなどで教えていただけるとうれしいです。

インストール

本家サイトのINSTALLATIONを参考に僕はtar.gzのファイルを手動どインストールして試してみました。

インストールはpearコマンドなどでもできるようです。

というか、www.twig-project.orgのフッタを見てみるとPEAR Serverも自作してること発見してびっくりました。

テンプレート側

テンプレート側のコードは下記のように記述します。

<html>
<title>title</title>
</html>
<body>
メリー {{ congratulation }}!!
メリー {{ congratulation|safe }}!!
</body>

実際のコード

テンプレートを呼び出す側のコードはTwig for Developersにあります。

これをほぼ丸写しして下記のようなコードを書いてみました。

<?php
require_once '/path/to/twig/lib/Twig/Autoloader.php';
Twig_Autoloader::register();

$loader = new Twig_Loader_Filesystem('/path/to/template/'); //(1)ファイルのほかに文字列直接とか配列を指定できる。
$twig = new Twig_Environment($loader,
array(
  'cache' => '/path/to/var/tmp/cache',
  'auto_reload' => true, //デフォルトがfalseなわきゃないと思うだけど
)
);
$escaper = new Twig_Extension_Escaper(true); //(2) デフォルトHTMLエスケープしてパラメータをつけるとエスケープしないようなコードがかける
$twig->addExtension($escaper);

$template = $twig->loadTemplate('nomal.html');
echo $template->render(array('congratulation' => 'X\'ss'));

実行してみると下記のようなHTMLが出力されます。

<html>
<title>title</title>
</html>
<body>
メリー X&#039;ss!!
メリー X'ss!!
</body>

(1) の部分でファイルからの読み込みが指定されてますが配列や文字列そのももの指定できるようような指定ができます。また、Loader自体の拡張も、たとえばMySQLやKVS的なものからデータを読み込むような指定もできます。

(2)の部分は、変数の出力時に何も指定しなければエスケープ処理を行うようにしてあります。 エスケープしない場合は{{hoge|safe}}のような記述します。 また上記設定しない場合は{{hoge|e}}とった感じの書き方でエスケープされます。

テンプレート継承

テンプレートを下記のように記述します。
base.html
<html>
<title>{% block title %}テスト{% endblock %}</title>
</html>
<body>
{% block body %}
本文だよ
{% endblock %}
</body>
title.html
{% extends "base.html" %}
{% block title%}継承テスト{% endblock %}

title.htmlを実行すると下記のような出力が行われます。

<html>
<title>継承テスト</title>
</html>
<body>

本文だよ

</body>

キャッシュされるテンプレート

どうやって継承とかしているのなーと思いキャッシュされたテンプレートを覗いてみました。

<?php

/* base.html */
class __TwigTemplate_0071f6af5144b1d5aaf62ae6db08f444 extends Twig_Template
{
  public function display(array $context)
  {
    // line 1
    echo "<html>
<title>";
    // line 2
    $this->block_title($context);
    echo "</title>
</html>
<body>
";
    // line 5
    $this->block_body($context);
    // line 7
    echo "
</body>
";
  }

  // line 2
  public function block_title($context)
  {
    echo "テスト";
  }

  // line 5
  public function block_body($context)
  {
    echo "
本文だよ
";
  }

}
title.html
<?php

$this->loadTemplate("base.html");

/* title.html */
class __TwigTemplate_f7f5efb7dcc094ca38d2c84bd671d4bc extends __TwigTemplate_0071f6af5144b1d5aaf62ae6db08f444
{
  public function display(array $context)
  {

    parent::display($context);
  }

  // line 2
  public function block_title($context)
  {
    echo "継承テスト";
  }

}
なるほど、クラスを生成して普通の継承を行っているんですね。 よく考えれば当たり前な気がしますが正直、Smartyなどのテンプレートエンジンは素のPHPっぽいテンプレートを返すのでクラスを吐き出すというのが自分的にはとても新鮮でした。

感想

触ってみた時間は短いですが、「あぁ考えられているな」と感じました。 そのほかにもSandboxやデバッグなどの機能があるみたいですが試せてはいません。 また、マルチバイトがかなり意識されていて、Filterのソースコードを見ると、mb_stringがあった場合には、それを使って処理するようになっています。海外のアプリケーションでmb_stringを使っているものを久しぶりに見ました。 PHPのテンプレートエンジンといえば、PHPそのものはもちろん、Smartyが有名ですが、これはこれで、メジャーバージョン3のベータ版が出ていたりしてそれはそれで興味深いですので正式版がでたら使ってみたいと思います。 何かのご参考になれば幸いです。