Twig の block を条件分岐して出力するとき、書き方によってエラーになる(Craft CMS)

Craft CMS のテンプレート中に Twig の block を使うときに陥りやすい落とし穴をご紹介します。

Craft CMS Logo

この記事は「Craft CMS Advent Calendar 2017」の6日目の記事です。Craft CMS というより Twig のお話になりますが

Twig で block を出力する方法は下記のように2種類あります。

{% block content %}{% endblock %}
{{ block('content') }}

全く同じ意味だと思いがちですが、テンプレートの書き方によってはエラーになってしまいます。 Craft CMS のテンプレートを書いているときにも陥る可能性が高い落とし穴ですのでご紹介します。

layout.twig

ベーステンプレートとなる layout.twig は下記のようになっているとします。

{% if side is defined %}
 <p>{% block content %}{% endblock %}</p>
 <p>sidebar</p>
{% else %}
 <p>{% block content %}{% endblock %}</p>
{% endif %}

side 変数がある場合とない場合で分岐しています。

test.twig

このベーステンプレートを使って、 /test という URL で表示するテンプレートを下記のように用意します。

{% extends 'layout' %}

{% block content %}
コンテンツ部分
{% endblock %}

これを表示すると、 The block 'content' has already been defined line 2. とエラーになってしまいます。

block-error-00-min.png

エラーにならないためには、 layout.twig を下記のようにする必要があります。

{% if side is defined %}
 <p>{{ block('content') }}</p>
 <p>sidebar</p>
{% else %}
 <p>{{ block('content') }}</p>
{% endif %}

ドキュメント

ドキュメントを見れば、function の方の block には、

if you want to print a block multiple times, use the block function ブロックを複数回出力する場合は、ブロック関数を使用する

と書いてあります。

単純なことですが、ハマリポイントな気がするのでシェアしておきたいと思いました。

以上です。

Published 2017-12-06
Updated 2019-06-25