ANNAIマガジン
twig
この記事は「 Working With Twig Templates 」の翻訳です。
この記事の目次

テンプレートのオーバーライド

DrupalではHTMLマークアップの生成に使用されるすべてのテンプレートをオーバーライドする事ができます。そのため、カスタムテーマ内で出力されるマークアップを完全に制御する事も可能です。ページを構成するHTMLから、小さなフィールドまであらゆる要素にテンプレートが存在します。

特定の命名規則に従うテンプレートをテーマフォルダに追加することで、Drupalのコアテンプレートをオーバーライドすることができます。

テンプレートをオーバーライドするには:

  1. オーバーライドするテンプレートを探します。
  2. オーバーライドするテンプレートファイルを元の場所からテーマフォルダにコピーします。
  3. (必要に応じて)テンプレートのオーバーライドによる変更を適用する対象に応じて、テンプレートの名前を命名規則に従って変更します。
  4. 好みに合わせてテンプレートを修正してください。

テンプレートファイルをテーマフォルダにコピーしてキャッシュをクリアすると、Drupalは標準のテンプレートファイルの代わりに追加したテンプレートを使用し始めます。Twigデバッグツールを使用すると、ページのどの部分にどのテンプレートが使用されているかを知ることができます。

Twigデバッグツールを有効にする方法については https://www.drupal.org/node/1906392 を参照してください。

テーマフックの利用による特定の対象へのテンプレートの適用(テーマフック名提案)

※ここでは「Suggestion(サジェスチョン)」を「提案」と翻訳しました。そのため、検索をする際には「Suggestion」で検索する事をお勧めします。

場合によっては、特定の対象にのみテンプレートの変更を適用したい事もあります。一般的な例としては、特定のコンテンツタイプのノードにのみノードテンプレートファイルのオーバーライドによる変更を適用したい場合です。

Drupalのテーマレイヤーでは命名規則に従って、ある特定の条件で利用される特定のテンプレートを対象にしたテンプレートの変更が可能です。

Articleノードをレンダリングする際、Drupalはまずnode--article.html.twigテンプレートを探し、テンプレートファイルが存在する場合はそれを使用します。node--article.html.twigテンプレートが存在しない場合、Drupalはデフォルトのnode.html.twigテンプレートに戻ります。テンプレートファイルで使用可能な名前をDrupalが決定するプロセスは「テーマフック名提案と呼ばれます。

前述した例のように、テーマフック名提案を利用する事で、テーマ内において、ある特定の対象のテンプレートを、特定の命名規則を持つテンプレートファイルでオーバーライドをすることができます。

コア、モジュール、テーマエンジン、およびテーマのすべてのレイヤーが提案を提供できます。以下の様なフックを使用して提案を追加または変更することが可能です。

hook_theme_suggestions_HOOK(array $variables)
hook_theme_suggestions_alter(array &$suggestions, array $variables, $hook)
hook_theme_suggestions_HOOK_alter(array &$suggestions, array $variables)

APIページはこちらです
https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Render!theme.api.php/function/hook_theme_suggestions_HOOK/8.2.x

キャッシュの再構築

テーマフック名提案の追加や変更を行った場合、Drupalは新しいテンプレートではなくキャッシュを参照している可能性があります。この問題が発生した場合は、キャッシュを削除してください。キャッシュを削除するには、「Drupalのキャッシュをクリアする」で説明した方法のいずれかを選択します。

背景情報

提案は、適切なルールに基づいてテンプレートを選択するようにシステムに指示するための、命名のヒントと考えることができます。

テンプレート名提案は、変更可能なテーマ名提案フックによって設定されます。

これらのフックは任意のモジュールまたはテーマが代替のテーマ関数または「テンプレート名の候補」を提供する事を可能にします。また、hook_theme_suggestions_HOOK()または、このフックの以前の呼び出しによって提供された提案を削除もしくは、並び替えする事を可能にします。

Drupalはどのようにパスに基づいてページテーマフックの提案を決定するのか

以下はtheme_get_suggestions()関数に基づく説明です:

あるページで利用可能なテンプレートの一覧はsystem_theme_suggestions_page() 関数によって呼び出された、theme_get_suggestions() 関数を通してDrupalにより生成されます。

ページのDrupalパスは、まずコンポーネントに分解されます。前述のように、Drupalパスはそのエイリアスとは違います。ページには以下の例のように固有のDrupalパスが割り当てられます。

http://www.example.com/node/1/edithttp://www.example.com/mysitename?q=node/1/editを例に取ると、Drupalパスは「node/1/edit」です。また、そのコンポーネントは 「node」、「1」、「edit」です。

次に、プレフィックスは「ページ」に設定されます。そして、すべてのコンポーネントに対して、以下のロジックが実行されます。

  1. コンポーネントが数字の場合、提案のリストに対して、「プレフィックス +  "__%" 」を追加します。
  2. コンポーネントが数字であるかどうかに関わらず、「プレフィックス +  "__" + そのコンポーネント」を提案のリストに追加します。
  3. コンポーネントが数字でない場合は、プレフィックスに 「"__"  + コンポーネント」を追加します。

コンポーネントのリストが繰り返し処理された後、ページがフロントページ(「管理>設定>システム>サイト情報」で設定されている)の場合、提案のリストに「page__front」が追加されます。

最終的に、提案を実際のファイル名に変換するために、 "__"は "--"になり、 ".html.twig"は提案に追加されます。したがって、node/1/editに対して、次のような提案が得られます。

  1. page.html.twig(これは常に提案です)
  2. page--node.html.twig(はpage__nodeに設定されています)
  3. page--node--%.html.twig
  4. page--node--1.html.twig(プレフィックスはコンポーネントが数値なので変更されません)
  5. page--node--edit.html.twig(プレフィックスはpage__node__editに設定されています)
  6. page--front.html.twig(ただし、node/1/editがフロントページの場合のみ)

ページが実際にレンダリングされると、最後の提案がチェックされます。提案が存在する場合は、その提案が使用されます。それ以外の場合は、次の提案がチェックされます。もちろん、オーバーライドしている提案が存在しない場合は、page.html.twigが最終的な提案となります。これはまた、page--front.html.twigが存在する場合、そのページが他の提案をオーバーライドする理由を説明します。これは、常に先頭ページとして指定されたページの最後の提案です。

Drupal 7との違い

以前はテンプレート名提案を変更するために、前処理関数で$ variables [ 'theme_hook_suggestion']と$ variables [ 'theme_hook_suggestions']を変更してテーマ名提案を導入しました。 Drupal 8では、モジュールとテーマはテーマ名提案を定義し、専用のフックで変更します。

 
フッターの採用情報
 
Kentaro Inoueの写真

この記事を書いた人: Kentaro Inoue

ANNAI株式会社
マーケティングマネージャー
サービスの設計・企画、マーケティング、採用戦略の立案などを担当。普段は新潟で猫と一緒に、時々海外からリモートで働いています。好きなモジュールはRulesとFlagです。

関連コンテンツ