Craft CMS のテンプレートでクエリを実行する方法について

Craft CMS のテンプレートでは、エントリをはじめとする任意のデータを柔軟に絞り込んで取得することができます。

Element Queries | Craft CMS Documentation | 4.x
https://craftcms.com/docs/4.x/element-queries.html

エレメントクエリと呼ばれるこの手法は、クエリの実行時にもいくつかの選択肢が用意されています。

そこで、今回はクエリの実行方法についてご紹介したいと思います。
これは Craft CMS Advent Calendar 2022 17日目の記事です。

抑えておきたいポイント

クエリの実行方法は公式ドキュメントの Query Execution に記載されています。

Element Queries | Craft CMS Documentation | 4.x
https://craftcms.com/docs/4.x/element-queries.html#query-execution

このうち、自分がよく使うものや便利だと感じているものは次の9項目です。

  • all( )
  • collect( )
  • one( )
  • nth( )
  • exists( )
  • count( )
  • ids( )
  • column( )
  • pairs( )

それぞれ、見ていきましょう。

all( )

フィルタ条件にマッチするデータをすべて取得します。

{% set entries = craft.entries()
  .section('news')
  .limit(10)
  .all() %}

取得件数を制限したい場合は、limit() を利用します。

collect( )

Craft 4 から新たに加わった機能で、all() の実行結果を Laravel Collection として取得します。

{% set entryCollections = craft.entries()
  .section('news')
  .with(['category_news'])
  .collect() %}

{% set categoryLabels = entryCollections
  .pluck('category_news')
  .collapse()
  .pluck('title')
  .join(', ', ' and ') %}

カテゴリ名: {{ categoryLabels }}

自分自身触りはじめた程度ではありますが、使い慣れると便利そうですね。

one( )

フィルタ条件にマッチする最初の1件を取得します。該当するデータがない場合、null が返ります。

{% set entry = craft.entries()
  .section('news')
  .one() %}

複数セットされている「カテゴリ」や「アセット」から1つだけ取り出す場合などに重宝します。

nth( )

フィルタ条件にマッチするN番目のデータを取得します。該当するデータがない場合、null が返ります。

{% set entry = craft.entries()
  .section('news')
  .nth(1) %}

0 からはじまるインデックス番号で指定する点だけ、注意しましょう。

exists( )

フィルタ条件にマッチするデータが存在するかどうか true または false で返します。

{% set entryQuery = craft.entries.section('news') %}

{% if entryQuery.exists() %}
(エレンメントがある場合の処理)
{% endif %}

count( )

フィルタ条件にマッチするデータの数を返します。

{% set count = craft.entries()
  .section('news')
  .count %}

ids( )

フィルタ条件にマッチするデータ ID の配列を返します。

{% set entryIds = craft.entries()
  .section('news')
  .ids() %}

「条件の異なる絞り込みをした上で、いずれにもマッチするデータだけを取りたい」といった場合、処理の負荷を軽減できるため重宝します。

column( )

フィルタ条件にマッチするデータの select() で指定した単一カラムの値を配列で返します。

{% set entryIds = craft.entries()
  .section('news')
  .select('title')
  .column() %}

paire( )

フィルタ条件にマッチするデータの select() で指定した2つのカラム値を key と value に持つ配列を返します。

{% set entryIds = craft.entries()
  .section('news')
  .select(['title', 'uri'])
  .paire() %}

最後に

今回はテンプレート上でクエリを実行する方法についてご紹介しました。
数は多いものの、ひとまず all()one()ids() 辺りを抑えておけば、問題ありません。

ただ、公式ドキュメントにも記載されているように PHP 上でも同様に利用できるため、モジュールやプラグインを開発する際にも役に立つと思います。