WordPress

WordPressの記事検索結果で検索キーワードをハイライト表示する

タイトルの内容の記事、たくさん出てきてどれも同じソースコードが載っているのですが、バグがあることに気づきましたので、修正した内容を公開します。ただ、バグがあるとはいえ、そういった記事がなければより困ってますので、公開してくださっている方々には感謝です。

WordPressの記事検索の機能

WordPressはサイト内の文言で検索する機能が標準で備わっています。検索対象として固定ページを含むのか、投稿ページだけにするのか、なども変更が可能です。

用いるには、

  • searchform.php
  • search.php

のファイルを用意し、それぞれに必要なソースコードを書く必要があります。

そもそも検索機能の実装をまだしてない方は、上記ファイル名などで検索して調べてみてください。

めざす形

次の画像はバグ修正後に「SEO アクセシビリティ」で検索したときの本サイトの検索結果画面です。このように、検索に用いた文言がハイライト表示されます。

バグ修正前だと、文言が検索したワードそのものの「SEO アクセシビリティ」に置き換わってしまい、
アクセシビリティとは|SEOにも関係します」が、
SEO アクセシビリティとは|SEO アクセシビリティにも関係します」
となってしまう、という不具合が発生します。
(そりゃ、「SEO アクセシビリティ」は「SEO アクセシビリティ」に関係するがな。。という変な文章になります)

よく記事に出てくるソースコード(バグあり)

functions.phpに以下のソースコードを追記すると、検索結果画面で検索キーワードがハイライトされる、という記事がたくさんあります。

しかしこのままだと、検索キーワードにスペースを含めてOR検索をしたときに、ハイライトされる部分がもともと1つの文言だったのが、検索した複数の文言に置き換わってしまいます。

function wps_highlight_results($text) {
if(is_search()){
   $sr = get_query_var( 's' );
   $keys = explode( " ", $sr );
   $text = preg_replace('/('.implode('|', $keys) .')/iu', '<span class="search-highlight">'.$sr.'</span>', $text);
   }
   return $text;
   }
add_filter('the_title', 'wps_highlight_results');
add_filter('the_content', 'wps_highlight_results');
function empty_search( $query ) {
    if ( $query-&gt;is_main_query() &amp;&amp; $query-&gt;is_search &amp;&amp; ! $query-&gt;is_admin ) {
    $s = $query-&gt;get( 's' );
    $s = str_replace(' ',' ', $s );
    $query-&gt;set( 's', $s );
    }
}
add_action( 'pre_get_posts', 'empty_search' );

修正した内容

ソースコード

次のように書くと、問題が修正されます。

function wps_highlight_results($text) {
if((is_search())&&(!is_admin())){ //管理画面は除く
   $sr = get_query_var( 's' );
   $keys = explode( " ", $sr );
   foreach ( $keys as $key ) {
     if(strpos($text, $key) !== false){
        $text = preg_replace('/'. $key .'/', '<span class="search-highlight">' . $key . '</span>', $text);
        break;
     }
   }
   }
   return $text;
   }
add_filter('the_title', 'wps_highlight_results');
add_filter('the_content', 'wps_highlight_results');

解説

$keysは、検索キーワードが格納された配列になっています。

そのため、foreachifを使って配列の各要素(OR検索に用いた各ワード)が、文章置き換え部分に含まれるかどうかを判断し、含まれればそのワードを<span class="search-hightlight"></span>で囲む形に置き換える、という内容になっています。

出回っているソースコードだと、配列のままで置き換えているので、<span class="search-hightlight"></span>の中にすべての検索キーワードが含まれてしまうのです。

追記:

is_search()だと管理画面でカテゴリー(ターム)でフィルタリングをかけた時も発動してしまうと気づいたので、!is_admin()を条件に加えました。

ハイライト表示しなくてもスペース入れるとバグるよ、という方へ

デフォルトでは、半角スペースは問題なくOR検索してくれるのですが、全角スペースだとおかしくなると思います。

日本語を扱えるようにするプラグイン「WP Multibyte Patch」を入れれば、全角スペースで検索できるようになります。このプラグインは私も入れていますし、入れておくべきなので、これで問題ないとは思います。

もし「WP Multibyte Patch」プラグインを入れない場合は、以下のソースコードをfunctions.phpに書きます。全角スペースで検索できるようにしているというよりは、全角スペースを半角スペースに変換している形です。

まとめ

WordPressの検索機能のユーザビリティを向上する参考になれば幸いです。当方が制作するサイトは、デフォルトでこの状態にします!

著者のイメージ画像

BringFlower
稲田 高洋(Takahiro Inada)

2003年から大手総合電機メーカーでUXデザインプロセスの研究、実践。UXデザイン専門家の育成プログラム開発。SEOにおいても重要なW3Cが定めるWeb標準仕様策定にウェブアクセシビリティの専門家として関わる。2010~2018年に人間中心設計専門家を保有、数年間ウェブアクセシビリティ基盤委員も務める。その後、不動産会社向けにSaaSを提供する企業の事業開発部で複数サービスを企画、ローンチ。CMSを提供し1000以上のサイトを分析。顧客サポート、サイト運営にも関わる。
2022年3月にBringFlowerを開業し、SEOコンサル、デザイン、ウェブ制作を一手に受ける。グッドデザイン賞4件、ドイツユニバーサルデザイン賞2件、米国IDEA賞1件の受賞歴あり。
プロフィール詳細