モノノフ日記

普通の日記です

Twigをもっと活用しよう :Symfony Advent Calender 2011 JP - 9日目 -

Symfony Advent Calendar JP 2011 : ATND 9日目の記事です。

Symfony2.0.7が昨日リリースされましたね。今回のアップデートで個人的に熱かったのはSymfony2にバンドルされるTwigのバージョンがv1.1.2からv1.4.0へアップグレードされた所です。Twigは便利な機能もいっぱいありますのでこの機会に紹介したいと思います。

for

お馴染みのループに使う構文です。一般的な使い方はこうです。

<ul>
    {% for item in article %}
        <li>{{ item.title }}</li>
    {% endfor %}
</ul>

もちろん配列の添字にもアクセスできます。

<ul>
    {% for key, item in article %}
        <li>{{ key }}:{{ item.title }}</li>
    {% endfor %}
</ul>

「..」というオペレータを使えば連続した値の定義が可能です。range関数も別途定義されています。

{% for i in 0..10 %}
    * {{ i }}
{% endfor %}

文字列でも大丈夫。

{% for letter in 'a'..'z' %}
    * {{ letter }}
{% endfor %}

ループ中の状態を表す変数として「loop」が用意されています。使い勝手はSmartyのiterationと同じです。

loop.index ループした回数(1から始まる)
loop.index0 ループした回数(0から始まる)
loop.revindex ループした回数(最後からカウント、1から始まる)
loop.revindex0 ループした回数(最後からカウント、0から始まる)
loop.first 最初の要素のときtrueを返す
loop.last 最後の要素のときtrueを返す
loop.length 配列の長さを返す
loop.parent ネストしてるループのとき、上階層のループ要素を取得

バージョン1.2からfor構文の中でif修飾子が使えるようになりました。修飾子好きとしては見逃せません。

<ul>
    {% for item in article if item.isPublic == 0 %}
        <li>{{ item.title }}</li>
    {% endfor %}
</ul>

set

Smartyでいうassignです。変数に値をセットできます。

{% set foo = 'foo' %}

配列も勿論OKです。Twigはperlrubyのように配列は「[]」、ハッシュ(連想配列)は「{}」を配列リテラルに使います。

{% set num = [1, 2, 3] %}
{% set str = {'foo': 'bar', 'hoge': 'fuga'} %}

文字列の連結は「~」(チルダ)を使います。

{% set foo = 'foo' ~ 'bar' %}

複数の変数を同時に定義することもできます。

{% set foo, bar = 'foo', 'bar' %}

複数の行をキャプチャすることもできます。{% endset %}を使いましょう。

{% set foo %}
  <div id="pagination">
    ...
  </div>
{% endset %}

spaceless

spacelessタグで囲ったHTMLから空白文字を取り除いてくれます。JavaScriptと連携するときに便利そうです。

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

{# 出力: be <div><strong>foo</strong></div> #}

バージョン1.1からタグレベルでの空白文字の制御が可能になりました。trimを実行したいタグの左右に「-」(ハイフン)をつけて利用します。

{% set value = 'no spaces' %}
{#- No leading/trailing whitespace -#}
{%- if true -%}
    {{- value -}}
{%- endif -%}

{# 出力: 'no spaces' #}

左右どちらかだけtrimする、という細かい制御もできます。

{% set value = 'no spaces' %}
<li>    {{ value -}}    </li>

{# 出力: '<li>    no spaces</li>' #}

divisibleby

割り切れる場合にtrueを返します。%演算子で余りが0(a % 3 == 0)と同じ動きです。

{% if loop.index is divisibleby(3) %}
    ...
{% endif %}

constant

TwigからControllerやEntityで定義しているconstの値にアクセスできます。名前空間から記述する必要があります。あとTwigのデフォルト仕様で文字列をescapeしてくれるのでバックスラッシュは2つ重ねで記述する必要があります。

Controllerに下記のようにconst定義をします。

<?php
namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Acme\DemoBundle\Form\ContactType;

// these import the "@Route" and "@Template" annotations
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class DemoController extends Controller
{
    const DEFAULT_LIMIT = 10;
    ...
}

Twigからはこのようにしてアクセスが可能になります。

{{ constant('Acme\\DemoBundle\\Controller\\DemoController::DEFAULT_LIMIT') }}

sameas

いわゆる「===」と同じです。値だけではなく型チェックもします。

{% set foo = "1" %}
{% if foo is sameas(1) %}
  check ok.
{% else %}
  check ng.
{% endif %}

{# 出力: 'check ng.' #}


Twigは拡張も書けるので、自作すれば何でもできてしまいます。ただビルトインされてる機能も必要最小限は組み込まれているので拡張書く前に公式マニュアル見直してみると良いかもしれません。

それではみなさんより良いTwigライフをお送りください!明日は@さんです!