2026年5月20日

2026年5月20日

WordPressの検索結果ページをカスタマイズする方法

はじめに

WordPressの検索結果ページは search.php テンプレートで制御します。pre_get_posts フックを使えばテンプレートを変更せずに検索結果の絞り込みや表示件数・投稿タイプのフィルタリングができます。

症状・原因

  • 検索結果ページのデザインを変えたい
  • 検索結果に特定の投稿タイプだけ表示したい
  • 検索結果の件数を変更したい
  • 固定ページを検索結果から除外したい

解決手順

ステップ1:search.phpテンプレートを作成する

# 親テーマのsearch.phpをコピー
cp wp-content/themes/parent-theme/search.php \
   wp-content/themes/my-child-theme/search.php

# 検索クエリを確認
wp eval "echo get_search_query() . PHP_EOL;"

# 検索結果のURLを確認
wp eval "echo add_query_arg('s', 'テスト', home_url('/')) . PHP_EOL;"

ステップ2:search.phpの基本構造

<?php
// wp-content/themes/my-child-theme/search.php
get_header();
?>
<main class="search-results">
    <header class="search-header">
        <h1 class="search-title">
            <?php
            if (have_posts()) {
                printf(
                    '「%s」の検索結果:%d件',
                    esc_html(get_search_query()),
                    $wp_query->found_posts
                );
            } else {
                printf('「%s」の検索結果は0件でした', esc_html(get_search_query()));
            }
            ?>
        </h1>
        <?php get_search_form(); ?>
    </header>

    <div class="search-results-list">
        <?php if (have_posts()): ?>
            <?php while (have_posts()): the_post(); ?>
                <article class="search-result-item">
                    <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                    <p class="post-meta">
                        <time><?php echo get_the_date(); ?></time>
                        <?php the_category(', '); ?>
                    </p>
                    <div class="excerpt"><?php the_excerpt(); ?></div>
                </article>
            <?php endwhile; ?>
            <?php the_posts_pagination(); ?>
        <?php else: ?>
            <p>検索結果が見つかりませんでした。別のキーワードでお試しください。</p>
        <?php endif; ?>
    </div>
</main>
<?php get_footer(); ?>

ステップ3:pre_get_postsで検索結果を絞り込む

// functions.php — 検索クエリをカスタマイズ
add_action('pre_get_posts', function(WP_Query $query): void {
    // 管理画面とメインクエリ以外は除外
    if (is_admin() || !$query->is_main_query()) return;

    // 検索結果ページのみ処理
    if (!$query->is_search()) return;

    // 検索対象の投稿タイプを指定(固定ページを除外)
    $query->set('post_type', ['post', 'product']);

    // 検索結果の表示件数を変更
    $query->set('posts_per_page', 20);

    // 特定カテゴリーを除外
    $query->set('category__not_in', [99]); // カテゴリーID:99を除外

    // 公開済みのみ
    $query->set('post_status', 'publish');
});

ステップ4:投稿タイプ別に検索結果を表示する

// 投稿タイプ別に検索結果をグループ表示
add_shortcode('grouped_search', function(): string {
    if (!is_search()) return '';

    $keyword   = get_search_query();
    $post_types = ['post' => '記事', 'product' => '商品', 'page' => 'ページ'];
    $output    = '';

    foreach ($post_types as $type => $label) {
        $results = new WP_Query([
            's'              => $keyword,
            'post_type'      => $type,
            'posts_per_page' => 5,
        ]);

        if ($results->have_posts()) {
            $output .= '<section class="search-group"><h2>' . esc_html($label) . '</h2><ul>';
            while ($results->have_posts()) {
                $results->the_post();
                $output .= '<li><a href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a></li>';
            }
            $output .= '</ul></section>';
            wp_reset_postdata();
        }
    }

    return $output;
});

ステップ5:検索結果ページのCSSをカスタマイズする

/* 検索結果ページのスタイル */
.search-header {
    padding: 30px 0;
    border-bottom: 2px solid #e0e0e0;
    margin-bottom: 30px;
}

.search-title {
    font-size: 1.5rem;
    margin-bottom: 16px;
}

.search-result-item {
    padding: 24px 0;
    border-bottom: 1px solid #e0e0e0;
}

.search-result-item h2 {
    font-size: 1.2rem;
    margin-bottom: 8px;
}

.search-result-item h2 a {
    color: #2271b1;
    text-decoration: none;
}

.search-result-item h2 a:hover {
    text-decoration: underline;
}

/* 検索キーワードをハイライト */
mark {
    background-color: #fef9c3;
    padding: 0 2px;
}

ステップ6:検索状況をWP-CLIで確認する

# 検索結果のテスト
wp eval "
\$q = new WP_Query(['s' => 'WordPress', 'posts_per_page' => 5]);
echo '検索結果数: ' . \$q->found_posts . PHP_EOL;
while (\$q->have_posts()) {
    \$q->the_post();
    echo get_the_title() . PHP_EOL;
}
wp_reset_postdata();
"

# 検索インデックスの最適化(SearchWPプラグイン使用時)
wp eval "echo 'WP_Query search works' . PHP_EOL;"

注意事項

  • pre_get_posts で検索クエリを変更する場合、必ず !is_admin() && $query->is_main_query() の条件を付けてください。管理画面の検索にも影響が出ます
  • 日本語の全文検索はデフォルトのMySQLでは精度が低い場合があります。SearchWPやElasticsearchとの連携を検討してください
  • $wp_query->found_posts で総検索結果件数を取得できます

まとめ

検索結果のカスタマイズは pre_get_posts で投稿タイプ・件数・除外カテゴリーを設定し、search.php でデザインを整えます。get_search_query() で検索キーワードを取得して「〇件の結果」を表示しましょう。

お気軽にご相談ください

お見積りへ お問い合わせへ