本文へ移動

実装例

WordPressで検索結果ページを作る方法
|WP_Queryとページネーションの実装

独自の検索結果ページでは、検索語を安全に受け取り、WP_Queryのsへ渡し、現在ページをpagedへつなぎます。標準のsearch.phpを使う場合との違いも先に整理します。

Huddly Huddly 投稿日: 2026年10月5日 読了目安: 4分

独自検索ではsとpagedを入力値へつなぎます

固定ページに独自の検索フォームを置く場合は、検索語を文字列に限定してsanitize_text_field()で処理し、$args[‘s’]へ渡します。ページ番号はget_query_var( ‘paged’ )から取得して、$args[‘paged’]へつなぎます。

標準検索のsearch.phpには検索用のメインクエリがあります。新しいWP_Queryは重ねません。「資料だけ」「事例だけ」と対象を分けるときは、この記事の独自検索が向いています。

標準検索と独自検索のどちらを作るか決める

同じ「検索結果ページ」でも、標準検索を整える作業と、特定用途の検索ページを新設する作業では入口が違います。標準検索は通常の検索フォームから?s=検索語で開くサイト全体の検索です。独自検索は「資料検索」のような固定ページを新しく作り、対象の投稿タイプ、入力欄、URL、0件表示を用途に合わせて用意します。

作りたいページ使うクエリ主なファイル・URL
サイト全体の標準検索既存のメインクエリsearch.php・?s=検索語
標準検索の対象を変更pre_get_postsでメインクエリを調整functions.phpまたは機能プラグイン
資料・事例などの専用検索新しいWP_Querypage-resource-search.php・固定ページURL

この記事は3つ目の独自検索を作る例です。標準検索で別のWP_Queryを作ると、URLのページ番号、総件数、テーマの検索表示と二重管理になりやすいため避けます。

なお、sの標準検索対象はタイトル・抜粋・本文です。タイトルだけに絞りたい場合は、WordPress 6.2以降のsearch_columnsを使います。対象列を先に決めたい場合は、記事のタイトルだけを検索する方法で対応バージョンと指定値を確認してから、この記事の完成例へ戻ってください。

WP Query Builderで検索語・件数・ページ番号を入力する

公開中のWP Query Builderで「詳細設定(全項目)」を選びます。確認用のデータには「ブロックテーマ」を含む通常投稿を6件用意し、1ページ3件の2ページ目を取得しました。

入力欄値意味
投稿タイプpost通常投稿だけを検索する
公開状態publish公開済みだけにする
取得件数31ページ3件
キーワード / sブロックテーマタイトル・抜粋・本文を検索する
ページ番号 / paged22ページ目を取得する
並び方向 / orderDESC新しい日付から並べる
並べ替えの基準 / orderbydate投稿日を基準にする

自動高速化はOFFにしました。ページネーションで総ページ数を使うため、no_found_rows => trueを自動追加しない状態にしておく必要があります。

WP Query Builderの検索欄へブロックテーマを入力し、3件、paged 2、日付降順を含むコードが生成された画面
公開中のWP Query Builder検索語と2ページ目を$argsへ反映

固定値で取得結果を確認したあと、検索語とページ番号をリクエスト値へ置き換えます。

次は、WP Query Builderがこの画面で生成したコードです。入力値、配列の順序、書式を変更せずに掲載しています。

引数や処理の一部分だけを示した例です。このまま単独で貼らず、テンプレート内のWP_Queryとループへ組み込んでください。

PHPgenerated-search-page-args.phpブロックテーマを含む通常投稿の2ページ目を3件取得する条件
$args = array(    'post_type' => 'post',    'post_status' => 'publish',    'posts_per_page' => 3,    's' => 'ブロックテーマ',    'paged' => 2,    'order' => 'DESC',    'orderby' => 'date');

sは検索語、posts_per_pageは1ページの件数、pagedは現在ページです。画面の2ページ目を固定値のまま貼ると、どのURLでも同じ結果になるため、完成例では動的な値へ置き換えます。

page-resource-search.phpへフォームと検索結果を実装する

クラシックテーマの子テーマへpage-resource-search.phpを作り、固定ページ「資料検索」に割り当てます。フォームはqという独自パラメーターを使い、空欄ではWP_Queryを実行しません。

PHPpage-resource-search.php独自検索フォーム、結果一覧、ページネーション、0件表示を実装する
<?php/* Template Name: 資料検索 */get_header(); $raw_search_term = isset( $_GET['q'] ) && is_string( $_GET['q'] )    ? wp_unslash( $_GET['q'] )    : '';$search_term = sanitize_text_field( $raw_search_term );$paged = max( 1, (int) get_query_var( 'paged' ) );?> <main id="primary">    <h1><?php echo esc_html( get_the_title() ); ?></h1>     <form method="get" action="<?php echo esc_url( get_permalink() ); ?>" role="search">        <label for="resource-search">記事を検索</label>        <input            id="resource-search"            name="q"            type="search"            value="<?php echo esc_attr( $search_term ); ?>"        >        <button type="submit">検索</button>    </form>     <?php if ( $search_term === '' ) : ?>        <p>検索語を入力してください。</p>    <?php else : ?>        <?php        $args = array(            'post_type' => 'post',            'post_status' => 'publish',            'posts_per_page' => 3,            's' => $search_term,            'paged' => $paged,            'order' => 'DESC',            'orderby' => 'date'        );         $search_query = new WP_Query( $args );        ?>         <h2>「<?php echo esc_html( $search_term ); ?>」の検索結果</h2>         <?php if ( $search_query->have_posts() ) : ?>            <p><?php echo esc_html( number_format_i18n( $search_query->found_posts ) ); ?>件見つかりました。</p>            <ul>                <?php while ( $search_query->have_posts() ) : ?>                    <?php $search_query->the_post(); ?>                    <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>                <?php endwhile; ?>            </ul>             <?php            echo wp_kses_post(                paginate_links(                    array(                        'current' => $paged,                        'total'   => (int) $search_query->max_num_pages,                    )                )            );            ?>        <?php else : ?>            <p>一致する記事はありません。別の言葉でも検索してみてください。</p>        <?php endif; ?>         <?php wp_reset_postdata(); ?>    <?php endif; ?></main> <?php get_footer(); ?>

qは文字列の場合だけ受け付け、配列など想定外の値は未入力として扱います。検索語をHTMLへ戻す箇所ではesc_attr()またはesc_html()、URLではesc_url()を使っています。SQLを自作して検索語を埋め込む例ではありません。

空文字をsへ渡すと検索条件が付かず、対象投稿を広く取得します。フォームは常に表示し、その下で検索結果を出す前に、検索語が空かどうかを分けてください。

検索結果は入力値、0件、複数ページで挙動が変わります。本番へ置く前にローカルまたはステージングで確認し、検証環境のバックアップとPHP条件も公式情報で確かめてください。

検索結果・0件・未入力を実データで確認する

分離したWordPress環境へ「ブロックテーマ」をタイトルに含む投稿を6件、含まない投稿を1件用意しました。投稿日降順で1ページ3件にすると、2ページ目はID100、101、102です。

ブロックテーマの検索結果6件を3件ずつに分け、2ページ目へID100、101、102が表示されたWordPress検証画面
実際のWP_Query結果2ページ目に4〜6件目を表示

同じ投稿データへs、posts_per_page、paged、日付降順を適用した結果です。

ページ番号だけでなく、found_postsが6、max_num_pagesが2であることも記録します。no_found_rows => trueを入れると総件数計算を省くため、このページネーション用途では使用していません。

0件と未入力を別の状態として表示する

存在しない検索語では0件案内を表示します。検索語が空の場合は、0件ではなく「検索語を入力してください」と案内し、WP_Query自体を実行しません。

一致しない検索語では一致する記事はありません、空欄では検索語を入力してくださいと表示された比較画面
検索状態の確認結果0件と未入力を混同しない

未入力では検索を実行せず、一致しない検索語だけを0件として扱います。

タイトルだけを検索したい場合はsearch_columnsを検討する

WordPress 6.2以降では、search_columnsでpost_title、post_excerpt、post_contentから検索対象列を選べます。タイトルだけへ限定すると、本文にだけ検索語がある投稿は対象外になります。

バージョン条件と、タイトル・抜粋・本文のどこで一致したかを確認する手順は、次の記事で実データを使って説明しています。対象列を狭める必要がある場合だけ、ここで確認してから完成例へ追加してください。

検索対象の列を選ぶ記事のタイトルだけを検索する方法|WP_Queryのsearch_columns記事を読む

2ページ目が同じ・404になる場合はURLとpagedを確認する

固定ページのページネーションでは、パーマリンク構造やpagedの取得元によって2ページ目が404になる場合があります。まず生成コードのpagedを固定値から動的値へ変えたか、ページリンクが同じ固定ページを向いているかを確認します。

症状が「2ページ目も1ページ目と同じ」「2ページ目だけ404」の場合は、原因が検索条件ではなくページ番号やパーマリンクの書き換え設定にあります。次の記事の切り分け順に沿うと、paged、page、max_num_pagesを順番に確認できます。

ページ送りの原因を調べるWP_Queryでページネーションが動かない原因記事を読む

標準のsearch.phpではメインクエリを重ねない

WordPress標準検索では、search.phpへ到達した時点で検索語とページ番号を持つメインクエリがあります。ここで同じ検索語のWP_Queryを新しく作ると、総件数やページ番号が二重になります。

標準検索の対象投稿タイプだけを変えたい場合は、pre_get_postsでis_main_query()とis_search()を確認して条件を変更します。独自ループとメインクエリのどちらを変えるべきか迷う場合は、次の記事で画面ごとの判断を先に確認してください。

メインクエリとの境界を確認するpre_get_postsとWP_Queryの違い記事を読む

検索語・件数・ページ番号を$argsへまとめる

固定値でコードを生成し、実データで検索結果と2ページ目を確認できます。完成時は入力された検索語と現在ページへ置き換えてください。

WP Query Builderの検索欄、ページ番号、Search Columnsをどの順で操作するかを画面付きで確認したい場合は、詳細設定の記事を先に読むと迷いません。生成コードをどのファイルへ置くかまで通して説明します。

詳細設定の操作を確認するWP Query Builderの詳細設定の使い方記事を読む

検索語・件数・ページ・0件を順番に確認する

検索結果の1件だけを見るのではなく、複数ページ、0件、未入力を同じデータで確認します。

独自検索ページの確認順

  1. 1
    対象投稿タイプと公開状態を決める
  2. 2
    固定した検索語で期待する投稿IDを確認する
  3. 3
    posts_per_pageより1件多い投稿を用意する
  4. 4
    1ページ目と2ページ目で重複・欠落がないか確認する
  5. 5
    found_postsとmax_num_pagesを確認する
  6. 6
    一致0件の案内を確認する
  7. 7
    空欄でWP_Queryを実行しないことを確認する
  8. 8
    検索語を画面へ戻す箇所のエスケープを確認する

検索結果ページの最終チェック

  • 標準検索か独自検索かを決めた
  • 検索語を文字列に限定し、wp_unslashとsanitize_text_fieldで処理した
  • 空検索語ではクエリを実行しない
  • pagedを現在ページへつないだ
  • 総ページ数を使うためno_found_rowsをtrueにしていない
  • 1・2ページ目の取得IDを確認した
  • 0件案内を用意した
  • 出力時のエスケープとwp_reset_postdataを確認した

検索とページネーションの公式資料を確認する

検索条件はWP_Query、入力値の処理とページリンクはそれぞれの公式関数で確認します。標準検索を変える場合はpre_get_postsの注意点も読んでください。

検索結果ページのよくある質問

独自検索で混同しやすいURL、空欄、並び順、対象列について短く整理します。

WP Query BuilderBuilderで条件を組み直す条件を選び、WP_Queryのコードを画面で作れます。Builderでクエリを作る

この記事を書いた人

Huddly

Web制作 / フロントエンドエンジニア

WordPressとフロントエンド実装で迷いやすい点を、公式情報と検証結果を分けながら、初学者にも追いやすい順序で整理しています。

この記事の検証情報

検証環境

WordPress
7.1.4
PHP
8.3.36
テーマ
wpq-media + DDEV
対象
カスタム投稿 / taxonomy / meta_query

更新履歴

  • 2026年10月5日 初回公開

この記事を活用する

あとで見返す・共有する

お気に入りに保存できます。役に立ったポイントは、いいねや共有で教えてください。

任意のご支援 役に立ったときだけ、活動を応援できます OFUSEはサイト・記事制作に使います。支援の有無で、読める内容や使える機能は変わりません。