これは Craft CMS Advent Calendar 2017 21日目の記事です。
Craft CMSのMatrix(行列)を使ってみた | </ Redamoon.Log>
https://redamoon.net/log/post/000039.html
昨日のぐっちーさんのブログ記事を拝見して、ふと「行列(Matrix)フィールドのテンプレートは {% include %}
タグを使う方が便利かも?」と感じたので、備忘録を兼ねてまとめてみます。
はじめに
コーディング時に Sass でスタイル定義をする場合、コンポーネントごとに .scss
ファイルを分けて @import
で読み込んでいる方も多いかと思います。
ファイルを細かく分けておくことで、時間を空けて修正が必要になった際もコードの可読性が高くなったり、プロジェクトをまたいで再利用できたりと、メリットがありますよね。
そこで、Matrix フィールドも同様に「ブロック単位でファイルを切り分けて、テンプレートを管理する」というのが今回の主旨です。
行列(Matrix)フィールドの作成
テンプレートを用意するにあたり、サンプルの 行列(Matrix)
フィールドを作成します。
下記を参考に「新しいフィールドを作る」画面に移動してください。
Craft CMS のフィールドについて理解しよう | BUN:Log
https://bunlog.dreamseeker.dev/learn-about-craftcms-fields
次に フィールドタイプ
までの項目を設定します。
ラベル | 値 |
---|---|
グループ | Default |
名前 | 本文用コンポーネント |
ハンドル | matrix_component |
フィールドタイプ | 行列 |
フィールドタイプのプルダウンから 行列
を選択すると、直下に 構成
が表示されますので4つのブロックを作成します。
見出しブロック
名前を 見出し
、ハンドルを heading
でブロックタイプを作成し、フィールドを1つ追加します。
ラベル | 値 |
---|---|
名前 | 見出し |
ハンドル | heading |
フィールドタイプ | プレーンテキスト |
設定後の画面サンプルも参考にしてください。
本文ブロック
名前を 本文
、ハンドルを body
でブロックタイプを作成し、フィールドを1つ追加します。
ラベル | 値 |
---|---|
名前 | 本文 |
ハンドル | body |
フィールドタイプ | プレーンテキスト |
改行を許可する | ON |
最初の行 | 4 |
設定後の画面サンプルも参考にしてください。
画像ブロック
名前を 画像
、ハンドルを image
でブロックタイプを作成し、フィールドを1つ追加します。
ラベル | 値 |
---|---|
名前 | 画像 |
ハンドル | image |
フィールドタイプ | ファイル管理 |
アップロードを単一フォルダに限定しますか? | ON |
ロケーションをアップロードする | 本文画像 ※ 本文画像 という名称のアセット・ソースを用意しておいてください。 |
許可されるファイルの種類を制限しますか? | ON ※ここでは 画像 のみ許可する形で設定します。 |
リミット | 1 |
モードを見る。 | リスト |
設定後の画面サンプルも参考にしてください。
アセット・ソースの作成は、下記も参考にしてください。
Craft CMS のファイル管理について理解しよう | BUN:Log
https://bunlog.dreamseeker.dev/learn-about-craftcms-assets
表組みブロック
名前を 表組み
、ハンドルを table
でブロックタイプを作成し、フィールドを1つ追加します。
ラベル | 値 |
---|---|
名前 | 表組み |
ハンドル | table |
フィールドタイプ | テーブル |
テーブルの欄
は、以下のように定義してください。
欄の見出し | ハンドル | 幅 | タイプ |
---|---|---|---|
ヘッダ | head | 一行テキスト | |
データ1 | data1 | 一行テキスト | |
データ2 | data2 | 一行テキスト |
設定後の画面サンプルも参考にしてください。
テンプレートファイルの構成
テンプレートの編集にあたり、ディレクトリ構成を確認しておきましょう。
craft
└── templates/
├── _entry.twig # エントリ詳細ページ
└── _matrix_component # matrix_component フィールドのパーツを格納するディレクトリ
├── body.twig # 本文ブロック
├── heading.twig # 見出しブロック
├── image.twig # 画像ブロック
└── table.twig # 表組みブロック
_entry.twig
に読み込みの定義を行い、エントリで追加されているブロックにあわせて _matrix_component
配下の対応するパーツを読み込むイメージです。
テンプレートファイルの作成
それぞれのテンプレートを作成していきましょう。
_entry.twig(エントリ詳細ページ)
{% extends "_layout" %}
{% block content %}
{# エントリに紐づく行列(Matrix)のブロックすべてをループ処理 #}
{% for block in entry.matrix_component.limit(null) %}
{# ブロックタイプごとのパーツを読み込み #}
{% include '_matrix_component/' ~ block.type ignore missing %}
{% endfor %}
{% endblock %}
entry.matrix_component.limit(null)
で、エントリに追加されている「本文用コンポーネント」フィールドのブロックすべてを取得します。それをループ処理し、{% include '_modules/matrix_component/' ~ block.type %}
でブロックタイプごとのテンプレートファイルを読み込みます。
このとき ignore missing
とすることで、読み込み対象のファイルが存在しない場合でも Twig エラーを回避できます。
_matrix_component/heading.twig(見出しブロック)
各ブロックごとのパーツは、存在するフィールドにあわせて調整する形となります。
{# フィールドの値を変数にセット #}
{% set block_heading = block.heading %}
{# 任意のマークアップで出力 #}
<h1>{{ block_heading }}</h1>
読み込み元で定義されている変数 block
をそのまま利用できるため、見出し
フィールドの値を block.heading
で取得しています。
_matrix_component/body.twig(本文ブロック)
{# フィールドの値を変数にセット #}
{% set block_body = block.body %}
{# 任意のマークアップで出力 #}
<p>{{ block_body | nl2br }}</p>
本文
フィールドは改行を有効にしているため、nl2br
フィルタで改行コードを br タグに変換します。
_matrix_component/image.twig(画像ブロック)
{# フィールドの値を変数にセット #}
{% set block_image = block.image.first() %}
{# 画像がセットされていれば、任意のマークアップで出力 #}
{% if block_image | length %}
<figure><img src="{{ block_image.url }}" alt="{{ block_image.title }}" ></figure>
{% endif %}
画像
フィールドにセットされた最初の画像を取得するため、 block.image.first()
としています。また {% if block_image | length %}
は画像がある場合のみ出力するための分岐処理です。
_matrix_component/table.twig(表組みブロック)
{# フィールドの値を変数にセット #}
{% set block_table = block.table %}
{# データがセットされていれば、任意のマークアップで出力 #}
{% if block_table | length %}
<table>
{% for row in block_table %}
<tr>
<th>{{ row.head | raw }}</th>
<td>{{ row.data1 | raw }}</td>
<td>{{ row.data2 | raw }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
画像ブロックと同様に {% if block_table | length %}
で入力値がない場合は table タグを出力しないよう調整しています。raw
フィルタは HTML タグを入力値に含む場合を想定した記述となります。
まとめ
今回は、行列(Matrix)フィールドのテンプレートを {% include %}
タグと組み合わせて最適化する方法についてまとめてみました。
ファイルが細かく分かれるため、ともすれば管理が面倒と感じられるかもしれませんが、個人的には便利だと思っているので一度試してみてください。