Twig は Silex のビューとして用いられているテンプレートエンジンです。
基本的な扱い方やインストール方法などについては前回の記事で取り扱ったので、今回はより実践的なテンプレートの組み方について説明します。
extends
一般的なサイトはヘッダー、フッター、サイドバー、メインコンテンツで構成されており、メインコンテンツ以外の場合は共通のものを使うケースが多いです。そのような場合 Twig では extends で土台となるテンプレートを利用します。ビューフォルダの中に「layouts」などの名前でフォルダを作り、base.twig というファイルを追加します。
layouts/base.twig
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <! DOCTYPE html> < html > < head > < meta charset = "utf-8" > < title >{% block title %}Twig{% endblock %}</ title > </ head > < body > < div id = "header" ></ div > {% block content %}{% endblock %} < div id = "footer" ></ div > </ body > </ html > |
base.twig にはメインコンテンツ以外の部分を記述しました。{% block ブロック名 %}〜{% endblock %} となっている部分にメインコンテンツが入ります。ブロック名は目的に合わせて好きな名前をつけることが出来ます。
ではこの base.twig を土台にトップページである index.twig をビューフォルダ内に作ります。(layouts フォルダ内ではありません)
index.twig
1 2 3 4 5 6 7 | {% extends 'layouts/base.twig' %} {% block title %}Home{% endblock %} {% block content %} < h1 >Hello, World!</ h1 > {% endblock %} |
{% extends 'ファイルの場所' %} と書くことで土台とするテンプレートを指定します。
{% block ブロック名 %} と {% endblock %} で挟まれた内容が base.twig の block 部分はこの内容に置き換えられ、結果として次の HTML が出力されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <! DOCTYPE html> < html > < head > < meta charset = "utf-8" > < title >Home</ title > </ head > < body > < div id = "header" ></ div > < h1 >Hello, World!</ h1 > < div id = "footer" ></ div > </ body > </ html > |
ブロック名「title」の部分は「Home」という文字に変わり、「content」の部分は「Hello, World!」で置き換えられています。
ブロックは省略することができ、省略した場合は親となるテンプレートの {% block ブロック名 %} と {% endblock %} で挟まれた内容が初期値として表示されます。例では親テンプレートに {% block title %}Twig{% endblock %} のようにして「Twig」というタイトルが初期値として用意されているため、小テンプレート index.twig で {% block title %} の箇所を削除した場合はタイトルとしてデフォルトの「Twig」という文字が使われることになります。
include
{% include 'ファイルの場所' %} を用いると他のテンプレートファイルを読み込むことが出来ます。
ヘッダー部分(id=header)とフッター部分(id=footer)をそれぞれ header.twig、footer.twig というファイルに切り分け、layouts フォルダに保存した上でそれらを base.twig から読み込んでみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <! DOCTYPE html> < html > < head > < meta charset = "utf-8" > < title >{% block title %}Twig{% endblock %}</ title > </ head > < body > {% include 'layouts/header.twig' %} {% block content %}{% endblock %} {% include 'layouts/footer.twig' %} </ body > </ html > |
出力される HTML は先程のものと同じです。このようにしてテンプレートファイルを分割しておくと、ホームページのみヘッダーを変えるなどの場合に便利です。
変数
コントローラーから渡された変数は {{ 変数名 }} の形で表示することが出来ます。PHP のように変数名の頭に「$」をつけることはなく、{{ var }} のようにします。
この方法で出力される値は <> などが適切に変換(エスケープ)された安全な状態で出力されます。
エスケープを行わずに出力する場合は filter の raw を使い、{{ 変数名|raw }} とすることでそのままの値を表示できます。filter には number_format や nl2br などの一般的な関数が多数用意されています。通常は必要ありませんが再度エスケープし直す場合は escape や短縮形の e というフィルターも用意されています。
また、「|」で区切ることで複数のフィルターをつなげて使うことも出来ます。
変数や文字列を連結する場合「~」(チルダ)を用いて繋ぎます。PHPと異なるので気をつけて下さい。
変数は基本的にコントローラーで用意されますが、ビュー側で set を使うことで変数を定義することも出来ます
{% set 変数名 = 値 %}
値が複数行の場合 {% set %}〜{% endset %} を使うことも出来ます
{% set foo %} line 1 line 2 line 3 {% endset %}
配列は PHP 同様 [1, 2, 3] のように表現しますが、連想配列の場合波括弧を用いて {'foo': 1, 'bar': 2} のようにする必要があります。
制御構文
ループ
Twig でループを作るには for 〜 in を用います。扱いは foreach と似ていますが順番に注意して下さい。
1 2 3 4 5 | < ul > {% for user in users %} < li >{{ user.name }}</ li > {% endfor %} </ ul > |
{% for key, value in users %} のようにしてキー名を取り出すことも出来ます。
PHP の for 近い使い方をする場合は次のように書きます。この例は 0〜10 までの数字を出力します。
1 2 3 4 5 | < ul > {% for i in 0..10 %} < li >{{ i }}</ li > {% endfor %} </ ul > |
ループ内では loop というオブジェクト変数が自動的に用意され、次の値を得ることが出来ます
loop.index | ループ回数(1から始まる) |
---|---|
loop.index0 | ループ回数(0から始まる) |
loop.revindex | ループ回数の逆順(1で終わる) |
loop.revindex0 | ループ回数の逆順(0で終わる) |
loop.first | ループが最初のとき true を返す |
loop.last | ループが最後のとき true を返す |
loop.length | 配列の長さ |
loop.parent | ループがネスト(入れ子)しているときの親の loop を取得 |
条件分岐
条件分岐には {% if 条件 %}〜{% endif %} が利用できます。
PHP 同様、{% else %} や {% elseif %} も用意されています。
1 2 3 4 5 | {% if foo == true %} < p >foo</ p > {% else %} < p >bar</ p > {% endif %} |
複合条件の場合「and」と「or」が使えます。
{% if foo == 1 and bar == 2 %}
その他の機能
Twig でコメントを 使う場合 {# 〜 #} を使います。これは HTML には出力されません。
また、複数行でも利用できます。
{# comment here #}
変数の内容を確認する場合のために dump() が用意されています。これは PHP の関数 var_dump() と同じもので、変数の詳細を表示できます。
{{ dump(foo) }}