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->is_main_query() && $query->is_search && ! $query->is_admin ) {
$s = $query->get( 's' );
$s = str_replace(' ',' ', $s );
$query->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
は、検索キーワードが格納された配列になっています。
そのため、foreach
とif
を使って配列の各要素(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の検索機能のユーザビリティを向上する参考になれば幸いです。当方が制作するサイトは、デフォルトでこの状態にします!