Wordpress の REST API で ACF のサブフィールドを使ってクエリする
サイドプロジェクトで Wordpress を Headless CMS として使っていて、そのときに ACF (Advanced Custom Field) で定義したフィールドを REST API のクエリで利用できなかった。それをどうやって解決したかという話。
TL;DR
ACF Better Search プラグインをインストールして search
クエリを使う。対象のサブフィールドが "監修者" で "田中太郎" でクエリしたい場合、"監修者" を ACF Better Search の検索対象にして /wp-json/wp/v2/posts?search=田中太郎
というクエリを投げる。
背景
Wordpress はバージョン 4.7 から REST API をデフォルトで提供していて、何もしなくてもGET /wp-json/wp/v2/posts
というパスで投稿をJSON 形式で取得できる。それをつかって Wordpress を Headless CMS として用いることができ、Next.js でブログのフロントを作って記事は Wordpress で入稿して管理するというようなことができる。
で、Wordpress の投稿にはさまざまなメタデータがつけられるようになっていて、Advanced Custom Field (ACF) もその一種。ACF はかなりメジャーなプラグインのようでみんなよく使っている。
この ACF で付与したメタデータで投稿をフィルタして一覧を取得したいと思ったのだけどデフォルトの REST API では ACF のメタデータはクエリに使えない。ACF も一部は REST API に対応していて category や custom-taxonomy などのトップレベルのものはクエリに使えるが、投稿に付けているメタデータ(=サブフィールド)は対象にならない。Stack Overflow にもそのように書かれていた。
ACF Better Search
自分で Wordpress に新しい REST API エンドポイントを組み込めばよさそうなんだけどめんどくさいし PHP は慣れてないのであまり書きたくない。1時間ほど Google をさまよっていたら ACF Better Seach というプラグインを見つけた。
これは Wordpress にある「検索機能」の検索対象に ACF のサブフィールドを加えてくれるというもの。Wordpress の REST API にもこの「検索機能」に対応する search というクエリがあり、これをインストールすれば対象に ACF のサブフィールドが加わる。
さらに、検索対象にするサブフィールドをしぼるオプションもある。
そして、ACF 側で検索対象にするサブフィールドを選ぶことができる。
これらを組み合わせることでめでたく ACF サブフィールドによるクエリ(=フィルタ)が実現できた。
もちろん、対象にしたいサブフィールドが複数、それらで同じ値がある場合にはちょっと工夫が必要になる。ただ、ACF サブフィールドは取得したデータに入っているし、REST API で取得後にアプリケーションレベルでさらにフィルタで十分実用に足りると思う。すくなくとも全件取得して自分でフィルタするよりはかなりマシだろう。
余談
なんか Wordpress とか ACF っていろいろトラブル抱えてるのね。これを調べながら初めて知った。Redis とか Elastic もこういうのあるよな~。