サイト内検索は、フォームと結果ページの2つを整えるだけで使い勝手が大きく変わります。まずは動く最小構成から。
<?php get_search_form(); ?>これで標準のフォームが出ます。見た目を変えたいときは、テーマにsearchform.phpを作るとその内容が使われます。
検索フォームを自作する
<form role="search" method="get" class="search-form" action="<?php echo esc_url(home_url('/')); ?>">
<label>
<span class="sr-only">サイト内を検索</span>
<input type="search" name="s" value="<?php echo esc_attr(get_search_query()); ?>"
placeholder="キーワードを入力" required>
</label>
<button type="submit">検索</button>
</form>必須の条件は3つです。
method="get"actionがhome_url('/')- 入力欄の
nameがs
この3つが揃っていれば、あとのマークアップは自由です。valueにget_search_query()を入れておくと、検索後もキーワードが残るので使いやすくなります。
検索結果ページ(search.php)
<?php get_header(); ?>
<main class="section">
<h1>「<?php echo esc_html(get_search_query()); ?>」の検索結果</h1>
<?php if (have_posts()) : ?>
<?php global $wp_query; ?>
<p class="result-count"><?php echo esc_html(number_format($wp_query->found_posts)); ?>件見つかりました</p>
<ul class="search-results">
<?php while (have_posts()) : the_post(); ?>
<li>
<a href="<?php the_permalink(); ?>">
<?php if (has_post_thumbnail()) : ?>
<?php the_post_thumbnail('thumbnail'); ?>
<?php endif; ?>
<h2><?php the_title(); ?></h2>
<p><?php echo esc_html(wp_trim_words(get_the_excerpt(), 80, '…')); ?></p>
</a>
</li>
<?php endwhile; ?>
</ul>
<?php the_posts_pagination(['prev_text' => '前へ', 'next_text' => '次へ']); ?>
<?php else : ?>
<p>「<?php echo esc_html(get_search_query()); ?>」に一致する記事は見つかりませんでした。</p>
<p>キーワードを短くする、別の言い方を試すとヒットしやすくなります。</p>
<?php get_search_form(); ?>
<?php endif; ?>
</main>
<?php get_footer(); ?>0件のときの案内を必ず用意します。「見つかりませんでした」で終わらせず、もう一度検索できるフォームや人気記事への導線を置くのが親切です。
べんりワザWordPressのページ送り(ページネーション)の出し方ページ送りの出し方はこちらべんりワザ抜粋(the_excerpt)の文字数と「続きを読む」を変える抜粋の文字数を調整する方法はこちら検索対象を絞る(固定ページや添付を除く)
既定では、公開されている投稿タイプがまとめて検索されます。投稿と商品だけにしたいならpre_get_postsで指定します。
function my_search_filter($query) {
if (is_admin() || !$query->is_main_query() || !$query->is_search()) {
return;
}
$query->set('post_type', ['post', 'shohin']);
$query->set('posts_per_page', 20);
}
add_action('pre_get_posts', 'my_search_filter');is_admin()とis_main_query()のガードは必須です。これが無いと管理画面の検索やサブループまで巻きこみます。
投稿タイプをフォーム側から切り替えることもできます。
<input type="hidden" name="post_type" value="shohin">商品ページ用の検索フォームでは、これを入れておくと商品だけを検索できます。
カテゴリや分類で絞りこめる検索フォーム
<form role="search" method="get" action="<?php echo esc_url(home_url('/')); ?>">
<input type="search" name="s" value="<?php echo esc_attr(get_search_query()); ?>">
<select name="season">
<option value="">季節を選ぶ</option>
<?php foreach (get_terms(['taxonomy' => 'season', 'hide_empty' => false]) as $term) : ?>
<option value="<?php echo esc_attr($term->slug); ?>"
<?php selected(get_query_var('season'), $term->slug); ?>>
<?php echo esc_html($term->name); ?>
</option>
<?php endforeach; ?>
</select>
<button type="submit">検索</button>
</form>タクソノミーのquery_varが有効なら、?s=…&season=winterのようなURLで自動的に絞りこまれます。selected()は選択状態を復元するWordPressの便利関数です。
カスタムフィールドも検索したいとき
WordPressの標準検索は、タイトルと本文(と抜粋)だけが対象です。カスタムフィールドの値は検索されません。
- タクソノミーに置きかえる——絞りこみで使う情報は分類にしておくと検索性が上がる
- 検索拡張プラグインを使う——カスタムフィールドやPDF内テキストまで対象にできるものがある
posts_searchフィルタで拡張する——SQLに手を入れるため上級向け
まずは「検索されたい情報を本文かタクソノミーに入れておく」という設計側の工夫がいちばん確実です。
べんりワザカスタムタクソノミーの作り方(register_taxonomy)絞りこみの軸をタクソノミーにする設計はこちら検索結果のURLをきれいにする
?s=キーワードではなく/search/キーワード/にしたい場合は、リダイレクトで変換できます。
add_action('template_redirect', function () {
if (is_search() && !empty($_GET['s'])) {
$url = home_url('/search/' . urlencode(get_query_var('s')) . '/');
if (untrailingslashit($_SERVER['REQUEST_URI']) !== untrailingslashit(wp_make_link_relative($url))) {
wp_safe_redirect($url, 301);
exit;
}
}
});見た目は整いますが必須ではありません。検索結果ページは検索エンジンにインデックスさせない設計が一般的なので、優先度は低めに考えてかまいません。
まとめ
- フォームは
searchform.phpに置くとget_search_form()から使われる。name="s"が必須 - 結果ページは
search.php。0件のときの案内と再検索フォームを必ず用意する - 検索対象は
pre_get_postsでpost_typeを指定して絞る(ガードを忘れない) - 標準検索はタイトルと本文だけ。絞りこみたい情報はタクソノミーにしておく
検索が使えるサイトは、記事が増えたときの回遊力がまるで違います。