twig埋め込みの扱い方あれこれ embed?extend?それともinclude??

お久しぶりです。山茶(やまちゃ)です。

さて、私は現在SymfonyというPHPフレームワークの案件に携わらせていただいております。
(Symfonyというか、EC-CUBEですが。)
ここ最近はSymfonyのドキュメント(英語)をひたすら読みつつ試行錯誤…するのがお仕事でした。

そんなSymfonyにはtwigというテンプレートエンジンが搭載されており、
twigでは、部品として作ったほかのテンプレートを埋め込んで使うことができる。
twigで埋め込みするといっても、実はいくつか方法があるので、まとめを作ってみました。

include(含む)

{% include "child.twig" %}

タグの場所に指定されたファイルまるごと埋め込み(挿入)。
https://twig.symfony.com/doc/3.x/tags/include.html

{% include 'template.html.twig' with {'name': 'Fabien'} %}

変数を渡すこともできる。

embed(埋め込み)

{% embed "parent.twig" %}~{% endembed %}

ブロック内に別のテンプレートを埋め込む。
囲まれた中に同じ名前のblockがあった場合、後の内容に書き換えられる。
単純に{% embed “parent.twig” %}{% endembed %}の空ブロックを置いた場合はincludeとほぼ同じ。

child.twig

{% embed 'template.twig' %}
{% block item1 %}
 <p>data1</p>
 <p>data2</p>
{% endblock %}
{% block item2 %}{% endblock %}
{% endembed %}

templete.twig

{% block item1 %}
 <p>data1</p>
 <p>data2</p>
 ...
{% endblock %}
{% block item2 %}
 <p>data1</p>
 <p>data2</p>
 ...
{% endblock %}

出力結果
<p>data1</p>
<p>data2</p>

#item2の中身はchild側で書き換えられて空に!

親をextendsして子ファイルを作って、ページの一部レイアウトを別ファイルからembedして…、特定のページだけその一部を書き換えて…
呼び出すのは子の名前で……というような使い方ができるそうです。
includeと同じようにwithキーワードも使用可能。
https://twig.symfony.com/doc/3.x/tags/embed.html

extends(継承)

{%extends 'base.twig' %}

extendsで指定したテンプレートにブロックの内容が埋め込まれる(上書き)。
子ファイルの名前で新しいテンプレートを作る。
親ファイルを継承して子ファイルを書く。extendsは複数書くことはできない。
https://twig.symfony.com/doc/3.x/tags/extends.html

親と子に同じ名前のブロックがあれば、子の内容で上書きされる。
{{ parent() }}で親ブロックの内容を表示することも可能。

block(block単位で利用)

{{ block("blockname", "files,twig") }}

これが記載された場所にそのブロックの内容を埋め込む(挿入)
別のtwigファイルにいくつかblockを記載していて、それの特定blockだけを使いたい場合に。

Blocks are used for inheritance and act as placeholders and replacements at the same time. They are documented in detail in the documentation for the extends tag.
https://twig.symfony.com/doc/3.x/tags/block.html

と書かれているように、継承(extends)の分類になるようです。