サイト内検索にGraphQLを使ってみる #craftcms

先日、 GraphQL のクエリとかを Craft CMS のテンプレート(Twig)でも使える!と1人感動したエントリを書いた。

だったらサイト内検索にも使えるのではないか?ということで試してみた。

検索結果表示コード一部

コードとしてはこんな感じで、検索結果の表示で entries をループする感じになる。

{% set query = craft.app.request.getParam('q') %}

{% set articles %}
query data($needle: String!)
{
  entries(section:"article",search:$needle){
    id
    title
    url
    postDate
    dateUpdated
    contentTag{
      title
      id
    }
  }
}
{% endset %}

{% set variables = {'needle': (query)} %}

{% set searchArticles = gql(articles, variables) %}

{% set entries = searchArticles.data.entries %}

variables をどう渡すのか悩んでたんだけど、 @BUN に教えてもらったエントリが非常に参考になった。

nystudio107 | Using the Craft CMS "headless" with the GraphQL API
https://nystudio107.com/blog/u...

感謝感謝 m(_ _)m

検索結果表示のループ

もともと、検索キーワードを元に検索して Craft のタグだけで検索&表示してたので、例えば検索結果の entries のループを回すときは

{% for entry in entries.all() %}

のような感じで all() が必要になるが、今回は必要ない。

{% if entries |length %}
  {% for entry in entries %}
  <div class="post-preview">
    <a href="{{ entry.url }}">
      <h2 class="post-title">{{ entry.title }}</h2>
    </a>

検索クエリからのrelationalなタグ部分の表示

タグの表示についても元々は

{% set tags = entry.contentTag %}
{% if tags|length %}Tag :
  {% for tag in tags.all() %}
    <a href="/tag/{{ tag.title }}">{{ tag.title }}</a>
  {% endfor %}
{% endif %}

みたいな感じなのが

{% if entry.contentTag|length %}Tag :
    {% for tag in entry.contentTag %}
      <a href="/tag/{{ tag.title }}">{{ tag.title }}</a>
    {% endfor %}
{% endif %}

だけになる。

この辺は切り替える場合はいくつか修正が必要そうではある。

ハッシュに変数を渡す

検索キーワード q を取り出して query にセットした後にどうやって渡すのか?というのが結構試行錯誤したのだけど、

{% set variables = {'needle': (query)} %}

という感じで、変数を ( ) で囲むことでいけるということを知った。

記事書いていただいてほんとありがたい。

https://ja.coder.work/so/twig/1504362

どっちがパフォーマンスがいいのか?とかはあるけど、そこはおって調べてみたいと思う(いつかやる)。

スマホでみてると気にならないのだけど、PCでみてると重い気がする。