2011/01/08

Symfony2 クイックツアー 第2部

日本Symfonyユーザ会にて日本語ドキュメントが公開されています。そちらを参考にしてください。
ビュー | Symfony2日本語ドキュメント
http://docs.symfony.gr.jp/symfony2/quick_tour/the_view.html
日本語訳(下書き):
Symfony - The View
http://symfony.com/doc/2.0/quick_tour/the_view.html

2. ビュー

本チュートリアルの第 1 部を読み終え、Symfony2 には、もう 10 分ほどの価値があると判断しましたね。 よくやった。 第 2 部では、Symfony2 のテンプレートエンジン Twig について詳しく学習します。 Twig とは、柔軟性、俊敏性、安全性を兼ね備えた PHP 用のテンプレートエンジンです。 Twig は、テンプレートを簡潔に、より読みやすくします。さらに、Web デザイナーにとっても、より親しみやすいものにしてくれます。

テンプレートには、Twig の代わりに、PHP を使用することができます。 Symfony2 は、両方のテンプレートエンジンをサポートしており、同レベルのサポートを備えています。

2.1. Twig の概要

Twig を覚えたいなら、公式ドキュメントを読むことを強くお勧めします。 本章は、主な概念だけの簡単な概要になります。

Twig テンプレートは、任意のテキストベースのフォーマット (HTML、XML、CSV、LaTeX、…) を生成することができるテキストファイルです。 Twig では、2 種類の区切り文字を定義しています:

  • {{ ... }}: 変数または式の結果を出力します。
  • {% ... %}: テンプレートのロジックを制御するタグ。例えば、for ループや if 文の実行に使用します。

下記は、ちょっとした基本を例示する、最低限のテンプレートになります:

<!DOCTYPE html>
<html>
    <head>
        <title>My Webpage</title>
    </head>
    <body>
        <h1>{{ page_title }}</h1>

        <ul id="navigation">
            {% for item in navigation %}
                <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
            {% endfor %}
        </ul>
    </body>
</html>

テンプレートに渡される変数には、文字列や配列、さらにはオブジェクトも取ることができます。 Twig は、それらの違いを抽象化します。また、ドット (.) 表記で変数の「属性」にアクセスできます:

{# array('name' => 'Fabien') #}
{{ name }}

{# array('user' => array('name' => 'Fabien')) #}
{{ user.name }}

{# force array lookup #}
{{ user['name'] }}

{# array('user' => new User('Fabien')) #}
{{ user.name }}
{{ user.getName }}

{# force method name lookup #}
{{ user.name() }}
{{ user.getName() }}

{# pass arguments to a method #}
{{ user.date('Y-m-d') }}
波括弧は、変数の一部ではなく、print 文であることを知っておくことが大切です。 タグ内で変数にアクセスする際は、波括弧で囲まないでください。

2.2. テンプレートの装飾

プロジェクトのテンプレートでは、たいていの場合、よくあるヘッダやフッタのような、共通の要素を共有しています。 Symfony2 では、独特の方法でこの問題を考えています。 つまり、あるテンプレートは別のテンプレートで装飾される、という考えです。 それはちょうど PHP クラスと同じように動作します。 すなわち、テンプレートの継承によって、サイトの共通要素のすべてを含み、さらに、子テンプレートがオーバーライドできる「ブロック(block)」を定義する、基本的な「レイアウト」テンプレートの構築を可能にしています。

index.html.twig テンプレートでは、extends タグで layout.html.twig を継承しています:

{# src/Sensio/HelloBundle/Resources/views/Hello/index.html.twig #}
{% extends "HelloBundle::layout.html.twig" %}

{% block content %}
    Hello {{ name }}!
{% endblock %}

HelloBundle::layout.html.twig 表記に心当たりがありませんか? そう、標準テンプレートを参照するのに用いたものと同じ表記ですね。(訳注: 「所属バンドル:コントローラ:アクション」が基本形です。) :: の部分は、コントローラ要素が空であることを単に意味し、テンプレートに対応するファイルは、views/ に直接保存されています。

それでは、layout.html.twig ファイルを見てみましょう:

{% extends "::base.html.twig" %}

{% block body %}
    <h1>Hello Application</h1>

    {% block content %}{% endblock %}
{% endblock %}

{% block %} タグによって、子テンプレートで代入できる 2 つのブロック (bodycontent) を定義しています。 block タグのすることといえば、子テンプレートが親テンプレートのブロック部分をオーバーライドしても構わないことを、テンプレートエンジンに知らせるだけです。 index.html.twig テンプレートでは、content ブロックをオーバーライドしています。 レイアウト自体を別のテンプレートによって装飾したように、テンプレートには基本的なレイアウトが定義されています。 テンプレート名のバンドル部が空 (::base.html.twig) の場合、ビューは、app/views/ ディレクトリを探索します。 このディレクトリには、プロジェクト全体に対するグローバルビューを格納します:

{# app/views/base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>{% block title %}Hello Application{% endblock %}</title>
    </head>
    <body>
        {% block body '' %}
    </body>
</html>

2.3. タグ、フィルター、及び関数

Twig における最も特徴的なことは、タグ、フィルター、及び関数による拡張性です。 Symfony2 には、Web デザイナーの仕事を楽にするために組込まれたモノが数多く同梱されています。

2.3.1. 他のテンプレートをインクルードする

コードスニペットをいくつかの明確なテンプレートに分けるのに一番良い方法は、別のテンプレートにインクルード可能なテンプレートを定義することになります。

hello.html.twig テンプレートを作成します:

{# src/Sensio/HelloBundle/Resources/views/Hello/hello.html.twig #}
Hello {{ name }}

それをインクルードするため、index.html.twig テンプレートを変更します:

{# src/Sensio/HelloBundle/Resources/views/Hello/index.html.twig #}
{% extends "HelloBundle::layout.html.twig" %}

{# index.html.twig から body ブロックをオーバーライドする #}
{% block body %}
    {% include "HelloBundle:Hello:hello.html.twig" %}
{% endblock %}

2.3.2. 他のコントローラを組込む

では、別のコントローラの実行結果をテンプレートに組込みたい場合はどうでしょう? コントローラの組込みは、Ajax による操作時、あるいは、メーンテンプレートに存在しない変数が組込のテンプレートで必要な場合に、とても役に立ちます。

fancy アクションを作成して、その実行結果を index テンプレートにインクルードしたい場合には、render タグを使用します:

{# src/Sensio/HelloBundle/Resources/views/Hello/index.html.twig #}
{% render "HelloBundle:Hello:fancy" with { 'name': name, 'color': 'green' } %}

ここで、HelloBundle:Hello:fancy 文字列は、Hello コントローラの fancy アクションを示しています。 また、シミュレートされたリクエストパスの値 (訳注: デフォルト引数値のこと) が引数として使用されます:

// src/Sensio/HelloBundle/Controller/HelloController.php

class HelloController extends Controller
{
    public function fancyAction($name, $color)
    {
        // $color 変数に基づいて、オブジェクトを作成する
        $object = ...;

        return $this->render('HelloBundle:Hello:fancy.html.twig', array('name' => $name, 'object' => $object));
    }

    // ...
}

2.3.3. ページ間のリンクを作成する

Web アプリケーションといえば、ページ間のリンク作成が必須ですね。 テンプレート内に URL をハードコーディングする代わりに、path 関数でルーティング設定に基づく URL を生成することができます。 そうすれば、ルーティング設定を変更するだけで、すべての URL を簡単に更新できます:

<a href="{{ path('hello', { 'name': 'Thomas' }) }}">Greet Thomas!</a>

path 関数は、ルート名とパラメータの配列を引数にとります。 ルート名は、ルートを参照する主キー (訳注: ルーティング設定ファイルで定義した名前) にします。 パラメータは、ルートパターンで定義されているプレースホルダーの値にします:

# src/Sensio/HelloBundle/Resources/config/routing.yml
hello: # ルート名
    pattern:  /hello/{name}
    defaults: { _controller: HelloBundle:Hello:index }
url 関数は、絶対 URL を生成します: {{ url('hello', { 'name': 'Thomas' }) }}

2.3.4. イメージ、JavaScript、スタイルシートなどのアセットをインクルードする

インターネットは、イメージ、JavaScript、スタイルシートが無いとどうなるのでしょう? Symfony2 では、それらアセットを手軽に扱うために、asset 関数を提供しています:

<link href="{{ asset('css/blog.css') }}" rel="stylesheet" type="text/css" />

<img src="{{ asset('images/logo.png') }}" />

asset 関数の主な目的は、アプリケーションの移植性を高めることにあります。 この関数のおかげで、テンプレートのコードを何も変更することなく、Web の root ディレクトリ下の任意の場所に、アプリケーションの root ディレクトリを移動することができます。

2.4. 出力のエスケープ

Twig は、デフォルトですべての出力を自動的にエスケープします。 出力のエスケープ、及び Escaper エクステンションの詳細については、Twig ドキュメントを参照してください。

2.5. 最後に

Twig はシンプルながらも強力です。 レイアウト、ブロック、テンプレート、及び、アクションが含まれていることによって、論理的かつ拡張性のある方法で、テンプレートがとても整理しやすくなります。

約 20 分間、Symfony2 だけを扱ってきました。 もう、それを用いてかなり凄いものを作れますね。 それこそが Symfony2 の実力です。 基本を学ぶのは簡単です。 また、このシンプルさには、とても柔軟なアーキテクチャーが隠されていることがすぐにわかるでしょう。

でも、先走ろうとしているなら。 まず、コントローラの詳細を学ぶ必要があります。 これはまさに本チュートリアルの次部のトピックになります。 さあ、Symfony2 に対して、もう 10 分ほどの準備はできましたか?

翻訳元:
moved PHP templates chapter to the cookbook - 2011-02-23 00:54:41
https://github.com/symfony/symfony-docs/blob/master/quick_tour/the_view.rst
注意: 誤訳が多く含まれている可能性があるため、文章の一部引用はなるべくしないでください。 掲載内容に関しては参考程度にしてください。 誤った情報を拡散しないようにご協力をお願いします。

0 コメント: