こんにちは。早いもので2018年もあと2ヶ月ちょっとですね。
最近twigテンプレートを触る機会が多いのですが、もどかしくなること結構ありませんか。
このデータを出力したいのに標準で使用できる変数には含まれていなかったり、ちょっとデータを加工したいのに意外と面倒だったり…。
そんなとき、twigの開発がスムーズになるよう手助けしてくれるモジュールがあるのをご存知でしょうか。
その名もTwig Tweakモジュールです。
Twig Tweakモジュール
Twig Tweakモジュールはtwigの拡張関数やフィルターを提供してくれるモジュールです。いつも通りインストールするだけで、特別な設定等は不要です。
このブログを公開した時点の最新バージョンは8.x-2.1です。
8.x-1系もありますが、1系と2系ではAPIが異なる部分があり、1系から2系に移行するにはtwigの修正がともないます。これから使われる方は2系を選択することをおすすめします。
それでは実際にどのような関数、フィルターが用意されているのかご紹介します。 なお、今回ご紹介する内容はこちらのCheat sheetを参考に作成しました。仕様についてもっと詳しく知りたい方は、Cheat sheetや実際のコードを見ていただくと良いかと思います。
8.x-2.1時点の関数
drupal_view
Viewsを出力するための関数です。内部的にはviews_embed_viewを実行しています。
{# 第3引数以降はViewsの引数として渡したい値です(省略可 #}
{{ drupal_view('viewの内部名称', 'display_id', foo, bar) }}
drupal_view_result
Viewsの結果を取得するための関数です。内部的にはviews_get_view_resultを実行しています。戻り値はResultRowクラスの配列で、結果がない場合は空の配列です。結果の有無をチェックする時に重宝しそうです。
{# 引数はdrupal_viewと同じ #}
{% set result = drupal_view_result('viewの内部名称', 'display_id', foo, bar) %}
drupal_block
ブロックを出力するための関数です。が、ブロックの種別によって実際に使用する関数が異なるようなので、詳しくはこちらをご覧ください
{{ drupal_block('search_form_block') }}
{# wrapperなし #}
{{ drupal_block('search_form_block', wrapper=FALSE) }}
drupal_region
リージョンを出力します。第2引数にテーマを指定することが可能です(省略可)。
{{ drupal_region('region名', 'umi_sample') }}
drupal_entity
エンティティを出力します。ビューモードや言語も指定できます。
{# カスタムブロック #}
{{ drupal_entity('block_content', 1) }}
{# ノード #}
{{ drupal_entity('node', 3, 'teaser') }}
drupal_entity_form
エンティティの追加フォームまたは編集フォームを出力します。
{# ノードの編集フォームを出力 #}
{{ drupal_entity_form('node', 'nidの値') }}
{# 記事コンテンツの追加フォームを出力 #}
{{ drupal_entity_form('node', 'values={type: 'article'}') }}
drupal_field
特定のフィールドだけを出力します。こちらもdrupal_entity
同様、ビューモードや言語を指定できます。
{{ drupal_field('field_image', 'node', 4, 'teaser') }}
drupal_menu
メニューを出力します。levelや深さを指定することも可能です。
{{ drupal_menu('main', 2, 3, TRUE) }}
drupal_form
フォームを出力します。ソースを確認したところ引数名は$form_id
なのですが、内部的にはこちらの関数を実行しているようなので、実際はFormInterfaceを実装したクラス名またはそのクラスのインスタンスを指定する必要があるようです。第2引数以降はフォームに渡す引数を指定できます。
{# スラッシュはエスケープしてください #}
{{ drupal_form('Drupal\\user\\Form\\UserLoginForm') }}
drupal_image
画像を出力します。画像の指定はURIのほか、FID、UUIDでも可能です。
{{ drupal_image('public://sample.jpg', NULL, {alt: 'サンプル画像'}) }}
drupal_token
トークンの値を出力します。
{{ drupal_token('site:title') }}
使用するデータを指定することも可能です
{{ drupal_token('node:title', {node: node}) }}
drupal_config
configの値を出力します。引数にはconfigの名前と取得したいキー名を指定します。
{{ drupal_config('system.maintenance', 'message') }}
drupal_dump / dd
デバッグ用の関数です
{{ dd(variables) }}
drupal_title
タイトルを出力します
{{ drupal_title() }}
drupal_url
URLを出力します。Drupalコアにもurl
関数がありますが、コアの関数がルートを指定するのに対し、drupal_url
はパスを指定します。第2引数にはUrl::fromUserInput
で使用可能なオプションが指定できます
{{ drupal_url('node/5', {absolute: TRUE}) }}
drupal_link
リンクを出力します。第2引数以降はdrupal_urlと同様です
{{ drupal_link('リンクのテキスト', 'node/5', {attributes: {target: '_blank'}) }}
drupal_messages
Drupalのステータスメッセージをブロックのラッパー要素なしで出力します。
{{ drupal_messages() }}
drupal_breadcrumb
パンくずリストをブロックのラッパー要素なしで出力します。
{{ drupal_breadcrumb() }}
drupal_breakpoint
Xdebugのブレークポイントをtwigに置けるらしいです。(Xdebug使ってないので、気になる方はお試しください)
{{ drupal_breakpoint() }}
8.x-2.1時点のフィルター
token_replace
指定した文字列内に含まれるトークンを、対応する値に置換します。drupal_token
と似ていますが、残念ながらtoken_replace
はデータを指定することはできないようです
{{ '<h1>[site:name]</h1><div>[site:slogan]</div>'|token_replace }}
php
非推奨ですがphpの実行もできます。極力使わない方が良いでしょう...デフォルトでは無効になっているので、どうしても使用したい場合はsettings.phpに
$settings['twig_tweak_enable_php_filter'] = TRUE;
を追加してください。
{{ 'return date("Y-m-d");'|php }}
transliterate
翻字(日本語などをアルファベットに変換すること)を行います。
{# 結果は、konnichiha です #}
{{ 'こんにちは'|transliterate }}
check_markup
指定した文字列をテキストフォーマットに適合した形に変換します。
{{ '<b>bold</b><strong>strong</strong>'|check_markup('restricted_html') }}
truncate
文字の切り詰めを行います。内部的にはUnicode::truncate
を実行しており、引数も同じです。
{# 結果は、あいうえおかきくけこさ... です #}
{{ 'あいうえおかきくけこさしすせそ'|truncate(12, FALSE, '...') }}
with
Drupalコアのtwig関数であるwithout
とは逆に、レンダリング配列に要素を追加(または上書き)します
{{ content.field_image|with('#title', 'Override') }}
view
エンティティやフィールドのオブジェクトをレンダリング配列に変換します。ビューモードなどを指定することも可能です。
{{ node|view('teaser') }}
{{ node.field_image|view }}
Twig拡張機能はViewsでも使えるため便利
Twig Tweakモジュールで拡張された関数やフィルターは、もちろんViewsでも使用することができます。
例として、親子関係をもつコンテンツのケースを考えます。親の一覧があり、各行にはその親にひもづく子コンテンツを表示するような場合です。
子ビューは、コンテキスチュアルフィルターに親のIDを受け取り、その値によって絞り込むようにしておきます。
親ビューでは、非表示のフィールドとしてノードIDを追加します。そして、独自のテキストフィールドを追加し、
{{ drupal_view('子ビューの名前', '子ビューのdisplay id', nid) }}
とすると、それだけで各行に子ビューを表示することができます。
今まで同じことをしようとすると、親ビューと子ビューを作成した後に
template_preprocess_views_view_fields
等で入れ子したいViewsを取得し、$variables
に追加views-view-fields--xxx.html.twig
ファイルを追加し、先ほど追加したViewsを埋め込む
という2段階が必要でした。
しかしTwig Tweakモジュールを導入することでViewsの設定画面だけで完了し、コード量やテンプレートファイルも削減できるようになります。
まとめ
どのプロジェクトでも必ずしも必要というわけではありませんが、複雑なレイアウトのページが多いサイトなどテンプレート開発を避けられない場合は、痒いところに手が届くモジュールではないかと思います。
テンプレート開発がしんどいなあと感じた場合はぜひお試しください!
募集しています
スタジオ・ウミは「Drupal」に特化したサービスを提供する Drupal のエキスパートチーム。
フルリモート&フレックス制だから、働く場所を選ばず時間の使い方も自由です。
そんなワークライフバランスの整った環境で、当ブログに書かれているような
様々な技術を共に学びながら、Drupalサイト開発に携わってみたい方を募集しています。
まずはお話だけでも大歓迎!ぜひお気軽にご連絡ください。