Craft CMS で検索ページを作る方法をご紹介します。
Craft CMS では、とても簡単にキーワード検索のフォームを設置することができます。
今回はその方法をご紹介します。
ページのどこかに下記のような検索フォームを設置します。
<form action="{{ url('search/results') }}">
<input type="search" name="q" placeholder="検索">
<input type="submit" value="検索">
</form>
検索結果を表示するテンプレートを作成します。
今回は、上記の form
タグの action
属性に {{ url('search/results') }}
と指定しているので、検索結果ページは下記のように設置します。
craft/template/search/results.twig
なお、Craft のテンプレートについて知りたい方は @BUN さんの下記の記事を参考にしてください。
results.twig
には下記のように書きます。なお、ここでは _layout_base
というベーステンプレートを継承しています。
{# ベーステンプレートとして _layout_base を継承 #}
{% extends '_layout_base' %}
{# 出力対象のエントリを変数にセット #}
{% set query = craft.request.getParam('q') %}
{% set results = craft.entries({
section: 'blog',
search: {
query: query,
subLeft: true,
subRight: true,
order: 'score'
}
}) %}
{# results を20件ごとにページ分割 #}
{% paginate results.limit(20) as pageInfo, pageEntries %}
{% block mainContent %}
<div role="main">
<section id="posts">
<h2 style="padding-bottom: 20px;">検索結果</h2>
{% if results|length %}
<p>{{ results|length }} 件見つかりました。</p>
<ol>
{% for entry in pageEntries %}
<li>
<a href="{{ entry.url }}">
<time datetime="{{ entry.postDate.iso8601 }}">{{ entry.postDate|date("Y年m月d日") }}</time>
<div>
<span class="title">{{ entry.title }}</span>
</div>
</a>
</li>
{% endfor %}
</ol>
{% else %}
<p>「{{ query }}」が見つかりませんでした。</p>
{% endif %}
</section>
<article class="entry">
<nav class="pagination">
<ul>
{% if pageInfo.prevUrl %}
<li><a rel="prev" href="{{ pageInfo.prevUrl }}?q={{ query }}">前のページ</a></li>
{% endif %}
{% if pageInfo.nextUrl %}
<li><a rel="next" href="{{ pageInfo.nextUrl }}?q={{ query }}">次のページ</a></li>
{% endif %}
</ul>
</nav>
</article>
</div>
{% endblock %}
順を追って解説していきます。
{# ベーステンプレートとして _layout_base を継承 #}
{% extends '_layout_base' %}
ベーステンプレートを継承します。
{# 出力対象のエントリを変数にセット #}
{% set query = craft.request.getParam('q') %}
まず q
パラメータの値を変数 query
にセットします。
{% set results = craft.entries({
section: 'blog',
search: {
query: query,
subLeft: true,
subRight: true,
order: 'score'
}
}) %}
上記のように entries
に取得する条件をセットしてエントリを取得します。
section
で blog
セクションに限定query
に変数 query
を渡すsubLeft
と subRight
に true
をセットして、検索キーワードの左右にワイルドカードを付けたのと同じ状態する( *キーワード*
と同じ)order
に 'score'
をセットしてスコア順に並べる{# results を20件ごとにページ分割 #}
{% paginate results.limit(20) as pageInfo, pageEntries %}
これで 20 件ごとにページ分割できるようにします。
{% block mainContent %}
<div role="main">
<section id="posts">
<h2 style="padding-bottom: 20px;">検索結果</h2>
{% if results|length %}
<p>「{{ query }}」が {{ results|length }} 件見つかりました。</p>
<ol>
{% for entry in pageEntries %}
<li>
<a href="{{ entry.url }}">
<time datetime="{{ entry.postDate.iso8601 }}">{{ entry.postDate|date("Y年m月d日") }}</time>
<div>
<span class="title">{{ entry.title }}</span>
</div>
</a>
</li>
{% endfor %}
</ol>
{% else %}
<p>「{{ query }}」が見つかりませんでした。</p>
{% endif %}
</section>
検索結果を表示します。ポイントだけ解説します。
{% if results|length %}...{% else %}...{% endif %}
で検索結果がある場合とない場合を分岐しています。結果件数は {{ results|length }}
で出力できます。
{% for entry in pageEntries %}...{% endfor %}
で現在のページのエントリをループします。
ページ送りのリンクを表示します。
<article class="entry">
<nav class="pagination">
<ul>
{% if pageInfo.prevUrl %}
<li><a rel="prev" href="{{ pageInfo.prevUrl }}?q={{ query }}">前のページ</a></li>
{% endif %}
{% if pageInfo.nextUrl %}
<li><a rel="next" href="{{ pageInfo.nextUrl }}?q={{ query }}">次のページ</a></li>
{% endif %}
</ul>
</nav>
</article>
</div>
{% endblock %}
ページ送りのリンクを {{ pageInfo.prevUrl }}?q={{ query }}
のようにしてパラメータを渡して挙げるのがポイントです。
これだけでページ送り付きの検索ページを作ることができました。とても手軽ですね!
以上です。