Twig を使ってみる


Twig は PHP のテンプレートエンジン。ちょっと前までは PHP のテンプレートエンジンといえば Smarty なもんだと思っていたら、最近は Twig がよいと聞くので触ってみることにしました。

# composer をインストールする

`composer` とは、<q>PHPのパッケージの依存関係やバージョン管理を行う仕組み</q> だそうです。公式サイトのインストール手順は `composer` コマンドを使った説明になってるので、これに従って、まず先に `composer` をインストールします。

参考： http://d.hatena.ne.jp/brtRiver/20120610/1339350390


composer も Twig も、プロジェクト個別にインストールして使うことができます。この例では、twigTest という適当なディレクトリを作って、その中にインストールしています。

```bash:command
$ mkdir ./twigTest
$ cd ./twigTest/
$ curl -s http://getcomposer.org/installer | php
```
```bash:output
#!/usr/bin/env php
All settings correct for using Composer
Downloading...

Composer successfully installed to: /{$currentDir}/composer.phar
Use it: php composer.phar
```

この結果、カレントディレクトリに `composer.phar` がインストールされます。

# Twigをインストールする

```bash:command
$ php composer.phar require twig/twig:1.*
```

```bash:output
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing twig/twig (v1.15.0)
    Downloading: 100%         

Writing lock file
Generating autoload files
```

これを実行すると、カレントディレクトリに <code>composer.json</code>、<code>composer.lock</code> というファイルと合わせて <code>vendor</code> というディレクトリが作成されます。その中に、composer や twig に関するファイルがたくさん生成されます。

これでインストールは終了です。


# Twigを使う

公式サイトにあるサンプルコードを動かしてみます。
カレントディレクトリに <code>test.php</code> を作って、そこに下記の実装をします。

```php:twigTest/test.php
<?php
require_once './vendor/autoload.php';

$loader = new Twig_Loader_String();
$twig = new Twig_Environment($loader);

echo $twig->render('Hello {{ name }}!', array('name' => 'Fabien'));
?>
```

この実装例はシンプルなもので、テンプレートは、 `$twig->render()` に、文字列として渡されているもの `'Hello {{ name }}!'` がそれです。第2引数はバインドする変数で、連想配列として渡しています。

出力結果は次のようになりました。

```html:output
Hello Fabien!
```

連想配列のキー `name` に対応する値が、テンプレート中の <code>{{ name }}</code> 部分に置き換えられて出力されています。

とりあえず、基本的な使い方で動かすことができました。

# 基本的な機能をいくつか使ってみる

簡単に動かすことができたので、基本的な機能のいくつかを試してみようと思います。



## エスケープして出力

デフォルトの設定では、autoescapeがオンになっているそうで、何もしないとHTML特殊文字がエスケープされて出力されます。

```php:test.php
<?php
require_once './vendor/autoload.php';
$loader = new Twig_Loader_String();
$twig = new Twig_Environment($loader);

echo $twig->render('{{html}}', array('html' => '<p>Hello World</p>'));
?>
```
```html:output
&lt;p&gt;Hello World&lt;/p&gt;
```

明示的にエスケープする場合、`|e` または `|escape` をつけます。
※以下、$twigのロード部分は省略します。

```php:test.php
echo $twig->render('{{html|e}}', array('html' => '<p>Hello World</p>'));
```
```html:output
&lt;p&gt;Hello World&lt;/p&gt;
```

HTML以外の言語のエスケープをしたい場合、`escape` の引数に言語の名前を指定します。

```php:test.php
echo $twig->render('{{src|escape("html")}}', array('src' => '<p>Hello World!</p>'))."\n";
echo $twig->render('{{src|escape("js")}}', array('src' => 'document.write("Hello World");'))."\n";
echo $twig->render('{{src|escape("css")}}', array('src' => 'body{background-color:#eee;}'))."\n";
echo $twig->render('{{src|escape("url")}}', array('src' => 'http://www.pxt.jp/'))."\n";
echo $twig->render('{{src|escape("html_attr")}}', array('src' => 'attr="Hello World"'))."\n";
```
```html:output
&lt;p&gt;Hello World!&lt;/p&gt;
document.write\x28\x22Hello\x20World\x22\x29\x3B
body\7B background\2D color\3A \23 eee\3B \7D 
http%3A%2F%2Fwww.pxt.jp%2F
attr&#x3D;&quot;Hello&#x20;World&quot;
```



## エスケープしないで出力

あえてHTMLなどをそのままソースに出力したい場合は、`|raw' で戻すことができます。

```php:test.php
echo $twig->render('{{html|raw}}', array('html' => '<p>Hello World</p>'));
```
```html:output
<p>Hello World</p>
```

## 連想配列の値を表示

```php:test.php
echo $twig->render('{{val.key2}}', array('val' => array('key2'=>'Hello World1')))."\n";
echo $twig->render('{{val["key2"]}}', array('val' => array('key2'=>'Hello World2')))."\n";
```
```html:output
Hello World1
Hello World2
```

# オブジェクトへのアクセス

```php:test.php
<?php
$obj = new stdClass();
$obj->val = 'Hello World';
echo $twig->render('{{obj.val}}', array('obj' => $obj))."\n";
?>
```
```html:output
Hello World
```

オブジェクトのメソッドにアクセスする場合も、ドットシンタックスで辿るようです。次の例は [Pickles Framework](http://pickles.pxt.jp/) の `$px` オブジェクトのメソッドをコールする例。

```php:test.php
echo $twig->render('<a href="{{px.theme().href("/")}}">link</a>', array('px' => $px))."\n";
```

## その他の使い方

公式のドキュメントを参考にいろいろやってみましょう。

参考： http://twig.sensiolabs.org/doc/templates.html


# まとめ

Twig の Twig らしいところまでは体験できていないけど、基本的な動作の確認はできた。

いろんなサイトで調べると、テンプレートの継承ができる機能が醍醐味らしい。
でも、今日は眠いのでここまで、またいずれ続きをやってみたいと思います。


※この記事はこちらにアーカイブしました。→ http://www.pxt.jp/ja/diary/article/288/