【WordPress】サイト内検索を自作する方法|検索フォーム・結果ページ・検索対象の拡張

WordPressには標準で検索機能が備わっていますが、サイトの特定のニーズに合わせてカスタマイズされた検索機能を作成したい場合もあります。この記事では、カスタム検索フォームの作成から検索結果ページのカスタマイズ、検索対象の拡張方法までを解説します。

この記事でわかること

  • カスタム検索フォーム(searchform.php)の作成
  • 検索結果ページ(search.php)のカスタマイズ
  • 検索対象の投稿タイプを広げる正しい方法
スポンサーリンク

検索フォームの作成

WordPressのテーマフォルダーに searchform.php を作成し、以下のコードを追加します。

searchform.php:カスタム検索フォーム
<form role="search" method="get" class="search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
    <label>
        <span class="screen-reader-text"><?php echo _x( 'Search for:', 'label' ); ?></span>
        <input type="search" class="search-field"
            placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder' ); ?>"
            value="<?php echo get_search_query(); ?>" name="s" />
    </label>
    <button type="submit" class="search-submit"><?php echo esc_attr_x( 'Search', 'submit button' ); ?></button>
</form>

get_search_query() は既定で esc_attr() 済みの文字列を返すため、value 属性にそのまま出力しても安全です。

検索結果ページのカスタマイズ

検索結果の表示方法をカスタマイズするために、search.php をテーマに作成します。

search.php:検索結果ページ
<?php get_header(); ?>

<main id="main" class="site-main" role="main">

    <?php if ( have_posts() ) : ?>

        <?php while ( have_posts() ) : the_post(); ?>

            <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                <header class="entry-header">
                    <?php the_title( '<h2 class="entry-title"><a href="' . esc_url( get_permalink() ) . '" rel="bookmark">', '</a></h2>' ); ?>
                </header>

                <div class="entry-summary">
                    <?php the_excerpt(); ?>
                </div>
            </article>

        <?php endwhile; ?>

        <?php the_posts_navigation(); ?>

    <?php else : ?>

        <article class="no-results not-found">
            <header class="entry-header">
                <h1 class="entry-title"><?php _e( 'Nothing Found', 'textdomain' ); ?></h1>
            </header>

            <div class="entry-content">
                <p><?php _e( 'Sorry, but nothing matched your search terms. Please try again with some different keywords.', 'textdomain' ); ?></p>
                <?php get_search_form(); ?>
            </div>
        </article>

    <?php endif; ?>

</main>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

検索対象の投稿タイプを広げる

カスタム投稿タイプも検索対象に含めたい場合は、pre_get_posts アクションフックでメインの検索クエリに post_type を追加します。

functions.php:カスタム投稿タイプを検索対象に含める
function custom_search_query( $query ) {
    if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
        $query->set( 'post_type', array( 'post', 'custom_post_type' ) );
    }
}
add_action( 'pre_get_posts', 'custom_search_query' );
meta_queryを同時に設定してカスタムフィールドを検索対象にしようとしない
同じpre_get_posts内でmeta_queryを設定してカスタムフィールドも検索対象に加えようとする実装をよく見かけますが、これは動作を悪化させます。本番WPコアを確認したところ、検索時にmeta_queryを設定すると、標準検索の条件(タイトル・本文)とAND結合されます。その結果、「タイトル/本文にマッチかつカスタムフィールドにもマッチ」する投稿だけが返り、カスタムフィールドだけにキーワードがある投稿は見つからず、通常タイトルでヒットしていた投稿も検索結果から消えてしまいます。カスタムフィールドもOR条件で検索対象に加えたい場合は、posts_joinposts_whereposts_distinctフィルターを使った正しい実装が必要です。詳しくはカスタムフィールドを検索対象にする方法(posts_joinで正しく実装)で解説しています。

CSSで検索フォームのスタイルをカスタマイズ

検索フォームや検索結果ページのデザインをカスタマイズするために、テーマのCSSファイルにスタイルを追加します。

style.css:検索フォームのスタイル
.search-form {
    display: flex;
    margin: 20px 0;
}

.search-field {
    flex: 1;
    padding: 10px;
}

.search-submit {
    padding: 10px;
    background-color: #0073aa;
    color: #fff;
    border: none;
    cursor: pointer;
}

.search-submit:hover {
    background-color: #005177;
}

よくある質問(FAQ)

Q検索結果ページに表示件数や並び順を指定したいです。
Apre_get_posts$query->set('posts_per_page', 数値)$query->set('orderby', 'date')のように指定します。is_search()とis_main_query()のガードを必ず付けてください。
Q検索フォームを複数の場所(ヘッダーとサイドバーなど)に設置できますか?
Aget_search_form()を呼び出したい箇所に配置するだけで複数設置できます。テーマ内の複数箇所で同じsearchform.phpが使われます。
Qカスタムフィールドも検索対象に含めたい場合はどうすればいいですか?
Ameta_queryを使うと検索語とAND結合されてしまい逆効果です。posts_join・posts_where・posts_distinctフィルターを使った実装、またはRelevanssiなどの検索プラグインを検討してください。

まとめ

  • 検索フォームsearchform.phpで自由にデザイン
  • 検索結果search.phpでレイアウトをカスタマイズ
  • 投稿タイプの拡張pre_get_postspost_typeを追加
  • 注意:カスタムフィールドの検索追加にmeta_queryは使わない

標準の検索機能をより使いやすく、デザインに合わせたものにすることで、ユーザーの検索体験を向上させることができます。