[Twig]テンプレートの構成と使い方(include/extends)

テンプレートエンジンを使う場合、表示する画面ごとに一つのテンプレートで運用することは少ないと思います。
ベースとなるテンプレートを作って、各ページでカスタマイズして使いたい(extends)。
共通パーツを切り出して、必要なテンプレート内で呼び出したい(include)。
などなどあると思います。Twigのテンプレートの構成するうえで必要な、includeextendsの使い方を紹介したいと思います。

includeの使い方

共通するパーツをそれぞれテンプレート化して、他のテンプレートで使いまわすことができます。

基本的な使い方

// contents of test.twig
<div>this is test</div>

// index.twig include test.twig
<div>include test</div>
{{ include('test.twig') }}

// result
<div>include test</div>
<div>this is test</div>

ファイルのパスは、ファイルシステムで指定されたtwigのディレクトリがルートになります。
またインクルード元でアクティブな変数をインクルードしたファイル内でも使用可能です。

// index.twig include test.twig
{% set test_class = 'product_text' %}
<div>include test</div>
{{ include('test.twig') }}

// contents of test.twig
<div class="{{ test_class }}">this is test</div>

// result
<div>include test</div>
<div class="product_text">this is test</div>

上記はtest_classという変数を読み込んだtest.twig内で使用しています。
基本的な使い方は以上です。

includeの使用例

includeの詳細な使い方を一部紹介したいと思います。

インクルードしたファイルで使用できる変数を渡す

{{ include('test.twig', {foo: 'bar'}) }}

上記例だと、fooという変数をtest.twig内で使用可能になります。

インクルード元の変数にアクセスできないようにする

{{ include('test.twig', with_context = false) }}

test.twig内でインクルード元の変数を使用不可にします。

インクルードファイルが無い場合、emptyを返す

{{ include('test.twig', ignore_missing = true) }}

ignore_missingをセットしない場合は、exception(例外)扱いとなります。

extendsの使い方

extendsは、ベースとなるテンプレートを作成することができます。

// base.twig

<!DOCTYPE html>
<html>
    <head>
        {% block head %}
            <link rel="stylesheet" href="style.css"/>
            <title>{{ title|default('extends test page') }}</title>
        {% endblock %}
    </head>
    <body>
        <div id="content">
            {% block content %}{% endblock %}
        </div>
        <div id="footer">
            {% block footer %}
                Copyright
            {% endblock %}
        </div>
    </body>
</html>

上記のようなベースのtwigファイルを作成したとします。このファイルをextendsしたファイルでblockや変数を上書きすることが可能になります。そのまま、ベースの値を使用することも可能です。

{% extends "base.html" %}

{% set title = 'this is child page extends sample' %}
{% block head %}
    {{ parent() }}
    <style type="text/css">
        .text-red { color: #990000; }
    </style>
{% endblock %}
{% block content %}
    <h1>Test Content</h1>
{% endblock %}

上記例だと、変数titleを上書きして使用しています。
block contentを新たに設定し、block footerは設定していないので、ベースのブロックをそのまま使用しています。
block head部分のように、{{ parent() }}を使うことによって、ベースのデータを呼び出して使用することも可能です。

Twigおすすめの書籍

Twigだけに特化した書籍は読んだことがないのですが、AmazonのKindleにありました。
これと同じくらいブログでまとめられたらと思います。

テンプレートエンジンTwigを覚える本