Symfony2 コントローラーとTwig

写真バンドルを作成して基本的なページ作成方法がわかったら、Twigの使い方を学んだ方がよいです。Twig自体はSmartyのような独立したテンプレートエンジンですが、Symfony2ではそれなりに独特の設定方法があります。データの最終的なHTML出力はテンプレートを通して行うことになりますが、テンプレートはどこのテンプレートでもそうであるように共通ファイルの読み込みができるゆえにテンプレートと言っても過言ではありません。ですので、各共通のテンプレート(つまり、ヘッダ、フッタ、サイドバーみたいなもの)を読み込む方法とその設定方法紹介します。
Symfony2的にはこれらの動作を「デコレート」するという言い方をするらしいです。
http://docs.symfony.gr.jp/symfony2/quick_tour/the_view.html
というのも、前述したインクルードという概念とやや違って厳密には大きなテンプレートの枠にそのテンプレートを継承した小さなテンプレートを設定してゆくということになっているからです。インクルードと発想が逆ということになります。これをデコレーションと呼ぶのはインクルードではないという意味でもあるんですね。たぶん。

ページ生成のための基本テンプレートは各バンドル内のコントローラーに書かれているものになります。
return $this->render('AcmeTestBundle:Default:index.html.twig', array('name' => $name));
このテンプレートに対して親要素的な大枠のテンプレートを紐付けて、ページ生成のためのテンプレートをデコレーションと位置づけることができるかと思います。そのような設定をします。
コントローラーから指定したテンプレートは(そういう意味では)だいたいがデコレーションテンプレートということになります。各バンドルで作成されるページは、各ページ要素のパーツというわけです。大元の親テンプレートはただのキャンパス的なものであると考えてもようかろうと思います。

twigテンプレートのデコレート

いろいろできるのですが、ここでは大枠のテンプレートを
app/Resources/views/base.html.twig
であるというところではじめます。こちらのテンプレートは確かインストール時にデフォルトで入っている筈です。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>test templete</title>
</head>
<body>
ベースのテンプレート
{% block body %}{% endblock %}
{% block test %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>

例えばこんなようなものだったとします。メインのテンプレートには各ブロック(読み込むテンプレート)を設定します。ここでは、

  • {% block body %}{% endblock %}
  • {% block test %}{% endblock %}
  • {% block javascripts %}{% endblock %}

というブロックを設定しています。body,test,javascriptsという3つのブロックです。
これらを設定したら、今度は各ブロックごとの設定をします。各ブロックはバンドルで作成したものになります。バンドルで作成するtwigでは先のbase.html.twigを継承するような設定をします。(なんか感覚としてはclassの継承みたいな感じです。)
例えば、
src/[ネームスペース]/[バンドル]/Resources/views/Default/test.html.twig
のようなものがあったとすると、
{% extends '::base.html.twig' %}
の設定をテンプレートの冒頭で行います。これはメインのテンプレートを継承しているテンプレートであるぞという宣言みたいなものになります。これでbase.html.twigを読み込んでから所定のブロックを入れ込んでゆく設定になります。各ブロックは、
{% block [ブロック名] %}
ここにテンプレートブロックの内容を書く
{% endblock %}

という風に書きます。
全体としては、
{% extends '::base.html.twig' %}
{% block body %}<br>
[[block body]]<br>
test<br>
Hello {{ name }}!<br>
{% endblock %}
{% block test %}<br>
[[block test]]<br>
日本語はどうなんだろ。
{% endblock %}
{% block javascripts %}<br>
[[block javascripts]]<br>
Javascriptとか書く<br>
{% endblock %}

みたいな書き方をします。ちょっとややこしいですが、慣れるとそうでもないです。ブロック名はメインのテンプレートと実際のブロックの間で同名にしておけばそれを読んでくれます。違うバンドルで作成したテンプレートもメインのテンプレートの中にブロックとしてデコレートできます。またメインのテンプレートも通常のバンドルから作成することも可能です。
これで各バンドルの仮想パスにアクセスすると、メインのテンプレートが適用されます。

app/内ではなく通常のバンドル内にあるテンプレートをメインテンプレートにする場合は、そのままバンドル名と名前空間を記述します。
src/ANBLO/frameBundle/Resources/views/Default/mainframe.html.twig
をメインテンプレートにする場合は、
{% extends 'ANBLOframeBundle:Default:mainframe.html.twig' %}
と記述すればいいです。対応するパスがそのままテンプレートを指定するコードになってくるのでわかりやすいといえばわかりやすいですが、教えてくれないと全然わからないですね。