サイト内検索を拡張してくれる有名プラグインもあるのですが、今回は functions.php に記述して検索条件をカスタマイズする方法をご紹介します。
もくじ
プラグインを使うと本文の検索結果がでてこない?
実はこの方法を実践する前に、Search Everything と Relevanssi を試してみたのですが、何故か本文やタイトルに入っているキーワードにも関わらず、検索結果が『なし』になる状態が発生していました。
プラグインのおかけで、カテゴリー名やタグ名は問題なく検索結果にでてきましたが、細かいキーワードへの対応ができないほうが嫌だったので、今回の方法を導入してみました。
検索条件に、カテゴリー名、タグ名、投稿者名を追加
WordPress標準のサイト内検索では、『投稿ページ』と『固定ページ』のタイトルと本文、抜粋が検索対象となっています。
下記を functions.php に記述することで、検索範囲を カテゴリー名、タグ名、投稿者名まで広げることができます。
/**
* サイト内検索の範囲に、カテゴリー名、タグ名、を含める
*/
function custom_search($search, $wp_query) {
global $wpdb;
//サーチページ以外だったら終了
if (!$wp_query->is_search)
return $search;
if (!isset($wp_query->query_vars))
return $search;
// ユーザー名とか、タグ名・カテゴリ名も検索対象に
$search_words = explode(' ', isset($wp_query->query_vars['s']) ? $wp_query->query_vars['s'] : '');
if ( count($search_words) > 0 ) {
$search = '';
foreach ( $search_words as $word ) {
if ( !empty($word) ) {
$search_word = $wpdb->escape("%{$word}%");
$search .= " AND (
{$wpdb->posts}.post_title LIKE '{$search_word}'
OR {$wpdb->posts}.post_content LIKE '{$search_word}'
OR {$wpdb->posts}.post_author IN (
SELECT distinct ID
FROM {$wpdb->users}
WHERE display_name LIKE '{$search_word}'
)
OR {$wpdb->posts}.ID IN (
SELECT distinct r.object_id
FROM {$wpdb->term_relationships} AS r
INNER JOIN {$wpdb->term_taxonomy} AS tt ON r.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->terms} AS t ON tt.term_id = t.term_id
WHERE t.name LIKE '{$search_word}'
OR t.slug LIKE '{$search_word}'
OR tt.description LIKE '{$search_word}'
)
) ";
}
}
}
return $search;
}
add_filter('posts_search','custom_search', 10, 2);
※投稿者名を検索条件から外したい場合は、この部分を消してください。
OR {$wpdb->posts}.post_author IN (
SELECT distinct ID
FROM {$wpdb->users}
WHERE display_name LIKE '{$search_word}'
)
参考サイト:[WordPress] ユーザー名とか、タグ名・カテゴリ名も検索対象に
pre_get_posts で 検索結果のクエリーをカスタマイズ
続いて、検索時のクエリーに条件を追加します。
以下の内容を function.php に追記して保存します。
function change_posts_paging($query) {
// 管理画面やメインクエリーでない場合は除外
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
// 検索結果ページ
if ( $query->is_search() ) {
// 公開されてる記事のみ検索
$query->set( 'post_status', publish );
// 投稿のみ検索
$query->set( 'post_type', post );
// 表示したくないカテゴリーID
$query->set( 'category__not_in', 1 );
// 表示したくない投稿ID。arrayで複数指定可。
$query->set( 'post__not_in', array( 1, 2, 3, 4, 5 ) );
// 検索結果の表示順
$query->set( 'order', DESC );
return;
}
}
add_action( 'pre_get_posts', 'change_posts_paging' );
投稿タイプを追加する場合は、array 型で記述します。
カスタムポストタイプ(ex. movie )を含む場合もここに追加します。
$query->set( 'post_type', array( 'post', 'page', 'movie' ) );
※その他、具体的なパラメータは 関数リファレンス/WP Query を参照してください。
サイト内検索を行い、狙い通りの結果がでてきたら成功です。
参照サイト
[WordPress]pre_get_postsを使いこなす!pre_get_posts使い方まとめ