【EC-CUBE 4】Twig まとめ(1) ~継承やブロックについて~

EC-CUBE 4のテンプレートを開くと必ず出てくる {% extends %}{% block %}。この2つが分かるとTwigの読み方が一気に楽になります。EC-CUBEに最初から入っているファイルを教材にして、継承とブロックの仕組みをまとめました。

extends と block は結局なにをしている?

{% extends %} は「土台にするテンプレートの指定」、{% block %} は「土台のどこを差し替えるかの指定」です。土台側に空の受け口を置いておき、各ページはそこへ入れる中身だけを書きます。

{% extends 'default_frame.twig' %}

{% block main %}
    ここに書いた内容が、土台の {% block main %} の位置へ入る
{% endblock %}

この仕組みのおかげで、各ページに <html><head> を書かずに済んでいます。

本記事では、EC-CUBE(Symfony)で用いられるテンプレートエンジン『Twig』の基本となる、継承やブロックを中心にまとめています。EC-CUBE 4で用意されているTwigファイルを元に説明しているので、実際にコードを触りながら読むと理解が早いかもしれません。

【動作環境】EC-CUBEのバージョン:4.3.0 / サーバー:XServer

目次

Twigの基本記法 早見表

この記事で扱う記法の一覧です。表の右上のボタンで表全体をコピーできます。

記法役割
{# コメント #}コメントアウト。出力されない
{{ 値 }}変数や式の中身を出力する
{% extends ‘ファイル名’ %}指定したテンプレートを土台として継承する
{% block 名前 %} ~ {% endblock %}差し替え可能な区画を定義する
{% set 変数 = 値 %}テンプレート内で変数を設定する
{% if 条件 %} ~ {% endif %}条件によって表示を切り替える
{% for 要素 in 配列 %} ~ {% endfor %}繰り返し表示する
{{ 値|trans }}フィルターを通して加工した値を出力する

Twigについては以下の記事にもまとめていますので、あわせてご覧ください。

デフォルトのTwigテンプレート(TOPページ)から、Twigを理解する

EC-CUBE 4で最初から用意されているTOPページのTwigテンプレート(index.twig)は以下のようになっています。コードは一部省略しています。EC-CUBE管理画面の「コンテンツ管理」→「ページ管理」から実物を見られます。

{#
This file is part of EC-CUBE

Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.

http://www.ec-cube.co.jp/

For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% extends 'default_frame.twig' %}

{% set body_class = 'front_page' %}

{% block stylesheet %}
    <style>
      {# 〜略〜 #}
    </style>
{% endblock %}

{% block javascript %}
    <script>
      {# 〜略〜 #}
    </script>
{% endblock javascript %}

{% block main %}
    <div class="ec-sliderRole">
        <div class="main_visual">
            <div class="item slick-slide"><img src="{{ asset('assets/img/top/img_hero_pc01.jpg') }}"></div>
            <div class="item slick-slide"><img src="{{ asset('assets/img/top/img_hero_pc02.jpg') }}"></div>
            <div class="item slick-slide"><img src="{{ asset('assets/img/top/img_hero_pc03.jpg') }}"></div>
        </div>
    </div>
{% endblock %}

後半のdivタグを除き、一般的なHTMLタグ(<html><body>)は書かれていません。一方で {# #}{% %} で囲まれたTwig特有の記述が見られます。Twigテンプレートを使いこなすには、これらの記法を理解する必要があります。

{# ~ #} → コメントアウト

EC-CUBEのTwigテンプレートの冒頭数行には、{# #} で囲まれたコピーライトの記述がありますね。ここで囲まれた部分はコメントアウトで、書かれた内容は実行されず、出力もされません。

HTMLのコメントアウト(<!-- -->)とは書き方が違うので注意しましょう。

HTMLのコメントは「出力はされるがブラウザに表示されない」だけなので、ページのソースを見れば読めてしまいます。Twigのコメントは出力自体がされないため、開発用のメモを書くならこちらが安全です。

{% set %} → 変数設定

以下のように書くことで、テンプレート側で 変数 を設定できます。

{% set 変数 = 値 %}

先ほどのTOPページでは {% set body_class = 'front_page' %} と書かれており、bodyタグに付けるクラス名を変数として渡しています。詳しい内容は Twig まとめ(2) で解説しています。

{% extends %} → 継承

{% extends ファイル名 %} を最初に書いておくことで、指定したテンプレートを継承できます。継承とは、別で用意されているテンプレートを土台として読み込み、そこへ新しい内容を上書きして新たなテンプレートを作る機能です。

ここでは以下のような記述になっています。

{% extends 'default_frame.twig' %}

これは「default_frame.twig」というTwigテンプレートを継承し、新しいテンプレートを作ることを意味します。

継承とはどのような仕組みか?

「default_frame.twig」の中身を見ながら、継承の仕組みを見てみます。

まず「default_frame.twig」は src/Eccube/Resource/template の下に格納されています。他の記事で ファビコンの変更titleタグ の変更を行っている場合、app/template/default の下に「default_frame.twig」を新規作成している場合があります。その際はそちらを参照してください。

「default_frame.twig」の格納場所(FTPクライアントでの表示)

「default_frame.twig」の格納場所

「default_frame.twig」は以下のような構成になっています。コードが長いため一部を抜粋しています。

<!doctype html>
{#
 ~~~
#}
<html>
 <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

  ~~~

    <title>{{ BaseInfo.shop_name }}</title>

  ~~~

    <link rel="stylesheet" href="">

  ~~~

   {% block stylesheet %}{% endblock %}

  ~~~

 </head>
 <body>

  ~~~

   {% block main %}{% endblock %}

  ~~~

   {% block javascript %}{% endblock %}

  ~~~

 </body>
</html>

こちらのファイルでは <html><head><body> といった一般的なHTMLの記述になっていますね。titleタグやmetaタグも書かれています。

継承とは、この「default_frame.twig」をベースとし、継承先のTwigテンプレートの内容が反映されて新しいページが作られる、という仕組みです。TOPページのテンプレート「index.twig」はこれを継承しているため、<html><body> を書かなくてよいわけです。

TOPページに限らず、継承しているページはすべて同じように反映されます。レイアウトを統一でき、メンテナンスもしやすくなるというメリットがあります。

{% block %} → ブロック

Twigテンプレートでは、以下のようなブロックを用いた構文が使われます。

{% block 名前 %}
    〜〜〜
{% endblock %}

Twigでは、上記で囲まれた部分を「指定した名前のブロック」として扱います。

ブロックの内容が、継承元のTwigに上書き(オーバーライド)される

TOPページ「index.twig」には {% block main %}{% endblock %} で囲まれた部分に、スライド画像を表示するimgタグが3つ書かれています。また、継承元の「default_frame.twig」にも {% block main %}{% endblock %} の記述があります。こちらの中身は空です。

このように書くと、

  • 継承元「default_frame.twig」の {% block main %}{% endblock %} に、
  • 継承先「index.twig」の {% block main %}{% endblock %} の内容が、

上書き(オーバーライド)されます。同様に {% block stylesheet %}{% block javascript %} に書いた内容も、それぞれ同じ名前のブロックへ入ります。

ブロックは名前ごとに1対1で対応します。下の図で、記号がどこへ入るかを追ってみてください。

ブロック名継承先 index.twig に書いた中身入る場所(継承元 default_frame.twig)
stylesheet○○○○○head内
main△△△△△body内の本文位置
javascript×××××body内の末尾

継承元「default_frame.twig」

<html>
<head>
  <meta>
  <title></title>
  {% block stylesheet %}{% endblock %}
</head>
<body>
  {% block main %}{% endblock %}
  {% block javascript %}{% endblock %}
</body>
</html>

継承先「index.twig」

{% extends 'default_frame.twig' %}

{% block stylesheet %}
  <style>
    ○○○○○
  </style>
{% endblock %}

{% block main %}
  <div class="ec-sliderRole">
    △△△△△
  </div>
{% endblock %}

{% block javascript %}
  <script>
    ×××××
  </script>
{% endblock %}

最終的に生成される内容

<html>
<head>
  <meta>
  <title></title>
  <style>
    ○○○○○
  </style>
</head>
<body>
  <div class="ec-sliderRole">
    △△△△△
  </div>
  <script>
    ×××××
  </script>
</body>
</html>

EC-CUBEで用意されているページのほとんどには、最初に {% extends 'default_frame.twig' %} が書かれています。これをベースとすることで基本情報やレイアウトが統一され、各ページにはメインの内容だけを書けばよいためコードの可読性も上がります。

この仕組みを利用したカスタマイズ方法は、以下の記事で紹介しています。

2つ以上のテンプレートを継承できる?

できません。1つのテンプレートが継承できる土台は1つだけです。

{% extends %} を2回書くと、Twigは以下のエラーを出して停止します。

Multiple extends tags are forbidden.

2つ目が黙って無視されるのではなく、テンプレートの解析時点でエラーになる点に注意してください。EC-CUBE 4.3.0 は twig/twig 3.8.0 を使っており、このバージョンでは複数の {% extends %} が明確に禁止されています。

ただし、条件によって継承元を切り替えることは可能です。{% extends %} の記述自体は1つのまま、指定するファイル名を式にします。

{% extends is_mobile ? 'mobile_frame.twig' : 'default_frame.twig' %}

{% %} を使ったその他の記法

ここで紹介した以外にも、Twigテンプレートには {% %} というタグを使ってさまざまな機能が用意されています。

タグ役割
{% set %}変数設定
{% if %}条件表示
{% for %}繰り返し表示
{% with %}変数の有効範囲を限定する
{% include %}別のテンプレートを読み込んで差し込む
{% macro %}繰り返し使う部品を関数のように定義する

また、{{ 値|trans }} のように書くことで特殊な出力を行うフィルター機能もあります。それぞれ詳しくは以下の記事にて。

EC-CUBEのカスタマイズに関する記事

この記事に出てきた用語

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次