【WordPress】検索キーワードを強調表示する方法|複数単語対応・esc_attr()の罠に注意

【WordPress】検索キーワードを強調表示する方法 WordPress

WordPressサイトで検索機能を提供している場合、検索結果ページでキーワードがハイライト表示されていると、ユーザーが目的の情報にたどり着きやすくなります。この記事では、検索キーワードを検索結果ページ内で自動的に強調表示する方法を、見落とされがちな2つの落とし穴とあわせて解説します。

この記事でわかること

  • get_search_query()が既定でエスケープ済みの文字列を返す罠
  • 複数単語の検索語に対応する正しいハイライト方法
  • the_title/the_excerptへの適用とスタイル設定
スポンサーリンク

検索キーワードを取得する

検索結果ページ(search.php または archive.php など)で現在の検索キーワードを取得するには get_search_query() を使います。

現在の検索キーワードを取得
$search_query = get_search_query( false );
get_search_query()は既定でesc_attr()済みの文字列を返す
get_search_query()引数無しで呼ぶと、検索ボックスの value 属性などにそのまま埋め込めるようesc_attr() でエスケープされた文字列が返ります。この状態の文字列を正規表現のパターン構築に使うと、検索語に &<>" のような文字が含まれる場合(例:「Q&A」で検索)、エスケープ後の文字列でパターンを作ってしまい、実際のタイトル・抜粋内の生の文字とは一致せずハイライトされません。HTML出力に使うのではなく正規表現の元データとして使う場合は、get_search_query( false ) で生の文字列を取得してください

本文内のキーワードをハイライト表示する関数を作成

検索キーワードに一致する部分を <span class="highlight"> で囲む関数を functions.php に追加します。WordPressの標準検索は複数単語を個別の単語としてAND条件でマッチさせるため、ハイライト側も検索語をスペースで分割し、それぞれの単語を個別にハイライト対象にします。

functions.php:複数単語に対応したハイライト関数
function highlight_search_keywords( $text ) {
    if ( ! is_search() ) {
        return $text;
    }

    $query = get_search_query( false ); // 生の検索語を取得(esc_attr()されていない)

    if ( '' === trim( $query ) ) {
        return $text;
    }

    // 検索語をスペースで分割し、単語ごとにハイライト対象にする
    $terms = preg_split( '/\s+/u', trim( $query ), -1, PREG_SPLIT_NO_EMPTY );

    if ( empty( $terms ) ) {
        return $text;
    }

    $quoted_terms = array_map(
        function ( $term ) {
            return preg_quote( $term, '/' );
        },
        $terms
    );

    $pattern = '/(' . implode( '|', $quoted_terms ) . ')/iu';

    return preg_replace( $pattern, '<span class="highlight">$1</span>', $text );
}
「wordpress plugin」の例
検索語が「wordpress plugin」の場合、単語を分割して wordpresspluginどちらか一方でも含まれていればハイライトされるようになります。これはWordPress標準検索が個々の単語をAND条件でマッチさせる(フレーズの並び順を問わない)挙動と一致します。

the_title や the_excerpt に適用する

表示部分で the_title()the_excerpt() を使用している場合は、次のように置き換えて適用します。

search.php:タイトル・抜粋にハイライトを適用
<h2><?php echo highlight_search_keywords( get_the_title() ); ?></h2>

<p><?php echo highlight_search_keywords( get_the_excerpt() ); ?></p>

スタイルを適用する

最後に、強調表示の見た目を整えるため、CSSでスタイルを設定します。

style.css:ハイライトのスタイル
.highlight {
  background-color: yellow;
  font-weight: bold;
}

関連する検索キーワードのハイライト

JavaScript側(クライアントサイド)でハイライトを実装したい場合は検索キーワードをハイライトする完全ガイド(mark.js・複数色・debounce最適化)も参考になります。

よくある質問(FAQ)

Qget_search_query()を引数なしで使うとどうなりますか?
Aesc_attr()でエスケープされた文字列が返ります。検索ボックスのvalue属性に埋め込む用途にはこちらが適していますが、正規表現のパターン構築など生の文字列が必要な場合はget_search_query( false )を使ってください。
Q複数単語で検索された場合もきちんとハイライトされますか?
A検索語をスペースで分割し、単語ごとに一致判定する実装にすることで対応できます。WordPress標準の検索は複数単語をAND条件(フレーズの並び順を問わない)でマッチさせるため、ハイライト側もそれに合わせる必要があります。
QハイライトによってHTMLタグが壊れることはありますか?
Aget_the_excerpt()が自動生成の抜粋(プレーンテキスト)であれば基本的に問題ありませんが、手動で書かれたHTML入りの抜粋やタイトルに検索語と同じ文字列がタグの属性などに含まれる場合、まれに意図しない箇所にタグが挿入される可能性があります。

まとめ

  • 正規表現の元データget_search_query( false )で生の文字列を取得する
  • 複数単語対応:検索語をスペースで分割しalternationパターンでマッチさせる
  • 適用the_title/the_excerptの出力をラップする

検索結果におけるキーワードのハイライト表示は、ユーザー体験の向上や検索結果の視認性向上に有効です。2つの落とし穴に注意しながら実装してみてください。