2019-10-30

Craft CMS でテンプレートから特定のエントリの特定のフィールドを取り出す #craftcms

Craft CMS のテンプレート(Twig)を書いていて、特定のセクションの特定のエントリを取り出して、そこで管理してるコンテンツを流用しようと考えた。

特定IDのエントリを取り出す

とりあえずは page セクションの ID が 907 のエントリを取り出すとしたらこんな感じ。

{% set serviceentry = craft.entries.section('page').id(907).one %}

特定のエントリとかを絞り込む方法は @BUN のエントリがわかりやすい。

Craft CMS で特定のエントリを取得する - Qiita
https://qiita.com/BUN/items/5e...

Matrix フィールドのブロックを絞り込む

これで該当のエントリに絞り込むことができて、今回とりたかったフィールドは Matrix フィールドの最初のブロックのデータを使いたかったかんじで。

ページフィールドでエディタブロックが入っていてその最初のブロックを使いたい、と。

Matrix はこれまでループで取り出すことが多かった。

Matrix Fields | Craft 3 Documentation
https://docs.craftcms.com/v3/m...

なので最初普通にループして取り出してた。

{% set serviceentry = craft.entries.section('page').id(907).one %}
      {% for block in serviceentry.page.all()|slice(0,1) %}
        {{block.richeditor}}
      {% endfor %}

serviceentry.page.all() で回しつつ slice してる時点で無駄だろうな、、、と思ったらやっぱり「 one でいけますよ」という @BUN のアドバイス。

一度自分でも one で試してたと思うのだけど、多分 one で取り出しながら for で回そうとしてたんだろうなぁと思われる。。。

one でとるとしたらこんな感じで取り出せる。

{% set serviceentry = craft.entries.section('page').id(907).one %}
{% set block = serviceentry.page.one %}
{{block.richeditor}}

ブロック(フィールド)の種類の分岐を入れる

んで、とりあえずこれで問題なく動いてはいるのだけど。

取り出してるデータがエントリのデータということで、操作して最初がリッチエディタのブロックになってないことも可能性としてはあり得るので、その辺はちゃんと考慮した方がよいよ、ということで。

分岐をいれるとしたらこんな感じになる。

{% set serviceentry = craft.entries.section('page').id(907).one %}
{% set block = serviceentry.page.one %}
{% if block.type == 'richeditor' %}
{{block.richeditor}}
{% endif %}

取り出す時点でタイプで分岐する

ここで @tinybeans がこんな感じで、取り出す時点でタイプも限定しておけば、安全、ということで。

{% set serviceentry = craft.entries.section('page').id(907).one %}
{% set block = serviceentry.page.type('richeditor').one %}
{{block.richeditor }}

.type. でつなぐ、と。

おー、なるほど!!スマートになった。

この場合は page フィールドで使われている
「リッチエディタブロックの最初のブロック」
を使うのか、
「純粋に最初のブロック」
を想定するかで少し変わるところはあるかもしれないけど、なるほどな、と。

まだまだテンプレート書く量が足りてないなー、と思いつつ2人には感謝感謝です。