WordPressの検索語を安全に表示する。get_search_query()の役割を理解する

CODE 08 検索入力から取得・エスケープ・表示までの流れを表したアイキャッチ

WordPressの検索結果ページでは、「何を検索した結果なのか」を画面へ残す必要があります。検索フォームから送られた文字をそのまま表示するだけに見えますが、URLから受け取った値をHTMLへ出す処理でもあります。

PROJECT 002で検索画面を作ったあと、検索語を取得するget_search_query()の役割を調べました。この記事では、検索語がどこから来て、どの場所へ、どの形で表示されるのかを最小例で確認します。

検索フォームのname=”s”が検索語になる

WordPressの標準検索では、入力欄の名前にsを使います。たとえば「バックアップ」と入力して送信すると、URLは次のような形になります。

https://example.com/?s=バックアップ

このsが、WordPressの検索クエリ変数です。get_search_query()は、その内容をテンプレート側で受け取るための関数です。

まずは検索フォームと結果表示を分ける

検索では、同じ文字列が二つの場所に現れます。

場所役割HTML上の位置
検索フォーム直前の検索語を入力欄へ残すvalue属性
検索結果の見出し何を検索した結果か伝える要素の本文

見た目は同じ検索語でも、HTML属性へ入れる場合と、本文として表示する場合では文脈が違います。ここを分けて考えると、エスケープの役割を理解しやすくなります。

入力欄ではget_search_query()を使う

検索フォームの最小例は次の形です。

<form role="search" method="get" action="<?php echo esc_url( home_url( '/' ) ); ?>">
  <label for="portal-search">サイト内検索</label>
  <input
    id="portal-search"
    type="search"
    name="s"
    value="<?php echo get_search_query(); ?>"
  >
  <button type="submit">検索</button>
</form>

get_search_query()は初期値では、取得した検索語をesc_attr()へ通して返します。つまり、HTML属性のvalueへ置くことを想定した形です。

WordPress標準の検索フォームも、入力欄の値にこの関数を使っています。検索後も入力欄へ検索語が残るため、利用者は条件を少し変えて検索し直せます。

結果見出しでは本文としてエスケープする

検索結果の見出しでは、検索語をHTML属性ではなく、文章の一部として表示します。文脈を明確にするなら、未エスケープの値を取得し、本文用のesc_html()を使えます。

<h1>
  「<?php echo esc_html( get_search_query( false ) ); ?>」の検索結果
</h1>

falseを渡すと、get_search_query()は関数内でesc_attr()を行わずに返します。その値を、表示先に合うesc_html()へ通しています。

公式ドキュメントも、未エスケープの値は後で適切にエスケープする場合だけ使い、未処理のまま出力しないよう説明しています。

取得と表示を一度に混ぜない

検索語を複数箇所で使う場合は、変数へ入れて役割を分けると追いやすくなります。

<?php
$search_query = get_search_query( false );
?>

<h1>
  「<?php echo esc_html( $search_query ); ?>」の検索結果
</h1>

<p>
  <?php echo esc_html( $search_query ); ?> に一致する情報を表示しています。
</p>

この例では、取得する処理は一度だけです。表示する場所ごとにesc_html()を使うため、「今は本文へ出している」とコードから分かります。

よくある混乱を三つに分ける

混乱確認すること
検索語が空になる検索結果ページか、URLにsがあるか
入力欄へ検索語が残らないvalue属性にget_search_query()があるか
エスケープが分からないHTML属性か、要素本文かを先に決める

get_search_query()は検索そのものを実行する関数ではありません。検索対象や並び順を変える役割でもありません。現在の検索語を、テンプレートで使える形にして取得する関数です。

検索結果が変わらないときに、この関数だけを調整しても検索条件は変わりません。取得・表示と、検索クエリの変更を分けることが大切です。

最小例で結果を確認する

確認は、複雑な検索画面を作る前に次の順で行えます。

  1. 検索フォームへ語句を入力する
  2. URLに?s=検索語が付くことを確認する
  3. 検索結果の見出しに同じ語句が表示される
  4. 入力欄にも検索語が残る
  5. 記号を含む検索語でもHTMLが壊れない

検索フォーム、結果見出し、結果一覧を一度に作り込まず、まず検索語の受け渡しだけを確認すると、問題の場所を切り分けやすくなります。

検索UIと検索語の処理を分けて理解する

検索入口、結果一覧、0件時の案内まで含めた画面設計は、WEB 08「WordPressの検索画面を整える」でまとめました。社内ポータルへ検索を加えた実制作の流れは、PROJECT 002 STEP 07「社内ポータルに検索を作る」に分けています。

今回扱ったのは、その中の「検索語を取得し、安全に表示する」という小さな部分です。フォームのname="s"、get_search_query()、表示先に合わせたエスケープ。この三つがつながると、検索結果ページのコードを読みやすくなりました。

参考:WordPress Developer Resources — get_search_query()、WordPress Developer Resources — get_search_form()