PHPテンプレートエンジンTwigの使い方

前回 TwigをPHPマイクロフレームワーク「Slim」で利用する - yohxxの忘れ物 でSlimフレームワークから
Twigを利用する方法を書いたので、今回はTwigの使い方について簡単にまとめる。

変数へのアクセス

Twigを利用する場合にPHP変数にアクセスするには下記のように記述する

{{foo}}       ← 変数titleの内容を出力
{{foo.bar}}    ← 配列foo['id']要素を出力
{{foo['bar']}}  ← 配列foo['id']要素を出力(上と同じ)

変数にアクセスする為にはドット(.)もしくはPHP配列にアクセスするような添字([])を利用します。
指定した変数もしくは要素が存在しない場合はnull値が返却される。


ちょっと面白い機能としてTwigでは利便性のために foo.barで指定した場合に下記のように処理を行うとの事を
公式ドキュメントに記載されている。

  1. foo が配列で bar が有効な要素であることをチェックします
  2. そうではない場合、かつ foo がオブジェクトである場合、bar が有効なプロパティであることをチェックします
  3. そうではない場合、かつ foo がオブジェクトである場合、bar が有効なメソッドであることをチェックします
  4. そうではない場合、かつ foo がオブジェクトである場合、getBar が有効なメソッドであることをチェックします
  5. そうではない場合、null の値を返します

PHPで書くとこんな感じか
※Twigのソース読んでいないので想像ですw

<?php
// 上のドキュメント的には$fooが指定された場合にこんな順番で判断されてるのかな?

if (is_array($foo) && isset($foo['bar'])) {
  return $foo['bar'];
} elseif (is_object($foo) && isset($foo->bar)) {
  return $foo->bar;
} elseif (is_object($foo) && is_callable(array($foo, 'bar'))) {
  return $foo->bar();
} elseif (is_object($foo) && is_callable(array($foo, 'getBar'))) {
  return $foo->getBar();
} else {
  return null;
}

フィルター

Smartyのmodifierみたいな機能としてフィルターがある。
使い方は簡単で、変数名の後にパイプ(|)を記述しその後にフィルター名を記述するだけ。
複数のフィルターをパイプでつなげて順番に処理した結果を出力することも可能。

{{ name|striptags|title }}  ← name からすべてのHTMLタグを除去しタイトルケースバージョンに置き換えます。

{{ list|join(', ') }} ← 引数を受け取るフィルターは関数呼び出しのように引数をかっこで囲みます。左の例ではコンマによってリストをつなげます。

組み込みのフィルターは他にもこんなのがある

  • date
  • format
  • replace
  • url_encode
  • json_encode
  • title
  • capitalize
  • upper
  • lower
  • striptags
  • join
  • reverse
  • length
  • sort
  • merge
  • default
  • keys
  • escape
  • e
  • raw

注意が必要なのは自動エスケープしている際にフィルターを利用してエスケープを無効にしたい場合、
昔のバージョンだとsafeというフィルターを利用していたが、現在のバージョンではrawに変更されている。
safeってのは現在は存在しない。
気をつけよう!
※フィルターそれぞれの使い方は別で書きたい

コメント

Twigのコメントなのでレスポンスとして返却されるHTMLには表示されないことを認識しておく。
{#から#}までの間をコメントアウトします。

{# ここからコメントアウト開始
  {% for user in users %}
      ...
  {% endfor %}
コメントアウト終了 #}

ホワイトスペースのコントロール

下記のように記述することでホワイトスペース(タブ、スペース、改行など)を除去できます。
Smartyの{strip}{/strip}と似たようなものっスかね。

{% spaceless %}
    <div>
        <strong>foo</strong>
    </div>
{% endspaceless %}

{# output will be <div><strong>foo</strong></div> #}

{# -を指定することでタグごとにホワイトスペースを除去できる #}
{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}

{# output 'no spaces' #}

{# タグの左側のホワイトスペースだけ除去 #}
{% set value = 'no spaces' %}
<li>    {{- value }}    </li>

{# outputs '<li>no spaces    </li>' #}

エスケーピング

Twig構文で利用している{}などを利用したい場合はエスケープする。

{{ '{{' }}

{# もしくは下記のように範囲を指定することもできる #}
{% raw %}
  <ul>
  {% for item in seq %}
    <li>{{ item }}</li>
  {% endfor %}
  </ul>
{% endraw %}


この辺りは公式ドキュメントに記載されているので読んでみると使い方わかるとおもう。
http://www.twig-project.org/documentation

この他にTwigの特徴としてテンプレート「継承」などがあるが、それはまた今度まとめることにする。