
WordPressでフリーワード検索すると、検索されない投稿があったり、検索されたくない固定ページがあったり。。。
意図した結果になるよう、フリーワード検索をしたいのだよ!
なんだか意図しない結果になるWordpressの「フリーワード検索」。
デフォルトで備わっている検索機能は、
- 半角スペースだと検索されるけど、「全角スペース」を入れると検索されない
- 「タイトルと本文と抜粋」だけ、「投稿と固定ページ」から検索している
これだけだと痒い所に手が届かない感じがする・・・てことで、
フリーワード検索の、検索対象や範囲を選んでカスタマイズする方法を紹介します。
- 全角スペースでも検索できる
- 固定ページを除外して検索できる
- カスタム投稿内を検索できる
- カテゴリー・タグ・カスタムタクソノミー・カスタムフィールド・ユーザー名から色々検索できる
全角スペースでも検索するには?
funcions.phpに下記コードをコピペ。
//検索結果<全角スペース対応>
function SearchFilter($query) {
if ( !is_admin() && $query->is_main_query() && $query->is_search() ) { //全角スペースでも検索可能にする
$s = $query->get( 's' );
$s = str_replace(' ',' ', $s );
$query->set( 's', $s );
}
}
add_action( 'pre_get_posts','SearchFilter' );
str_replaceを使って、全角スペースを半角スペースに置換することで、検索ができるというわけです。
検索するページを指定するには?
固定ページを除外して検索したり、カスタム投稿も検索する方法です。
funcions.phpに下記コードをコピペ。
//検索結果<カスタム投稿を含める・固定ページ除外>
function SearchFilter($query) {
if ( !is_admin() && $query->is_main_query() && $query->is_search() ) { //検索する投稿タイプ
$query->set( 'post_type', array('post', 'info', 'topics') );
}
}
add_action( 'pre_get_posts','SearchFilter' );
arrayの中身について、’post’は投稿ページを、’info’や’topics’などはカスタム投稿を指します。
固定ページを除外するには、array中に’page’ を入れなければOKです。
検索対象を広げるには?
カテゴリー・タグ・カスタムタクソノミー・カスタムフィールド・ユーザー名から検索する方法です。
funcions.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 = '%' . esc_sql( $word ) . '%';
$search .= " AND (
{$wpdb->posts}.post_title LIKE '{$search_word}'
OR {$wpdb->posts}.post_content 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}'
)
OR {$wpdb->posts}.ID IN (
SELECT distinct post_id
FROM {$wpdb->postmeta}
WHERE meta_value LIKE '{$search_word}'
)
OR {$wpdb->posts}.post_author IN (
SELECT distinct ID
FROM {$wpdb->users}
WHERE display_name LIKE '{$search_word}'
)
) ";
}
}
}
return $search;
}
add_filter('posts_search','custom_search', 10, 2);
- 19~27行目で、ターム類(カテゴリー・タグ・カスタムタクソノミー)を検索対象にしています。
- 28~32行目で、カスタムフィールドを検索対象にしています。
- 33~37行目で、ユーザーのブログ上の表示名を検索対象にしています。
それぞれ必要なところをピックアップしてコピペしてください。
~まとめるとこんな感じ~
上記すべてをまとめれば、functions.phpの記述内容はこちらになります。
//検索結果<全角スペース対応/カスタム投稿を含める・固定ページ除外>
function SearchFilter($query) {
if ( !is_admin() && $query->is_main_query() && $query->is_search() ) { //全角スペースでも検索可能にする
$s = $query->get( 's' );
$s = str_replace(' ',' ', $s );
$query->set( 's', $s );
}
if ( !is_admin() && $query->is_main_query() && $query->is_search() ) { //検索する投稿タイプ
$query->set( 'post_type', array('post', 'info', 'topics') );
}
}
add_action( 'pre_get_posts','SearchFilter' );
//検索対象<カテゴリー・タグ・カスタムタクソノミー・カスタムフィールド・ユーザー表示名から>
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 = '';
/*$search .= "AND post_type = 'post'";*/
foreach ( $search_words as $word ) {
if ( !empty($word) ) {
$search_word = '%' . esc_sql( $word ) . '%';
$search .= " AND (
{$wpdb->posts}.post_title LIKE '{$search_word}'
OR {$wpdb->posts}.post_content 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}'
)
OR {$wpdb->posts}.ID IN (
SELECT distinct post_id
FROM {$wpdb->postmeta}
WHERE meta_value LIKE '{$search_word}'
)
OR {$wpdb->posts}.post_author IN (
SELECT distinct ID
FROM {$wpdb->users}
WHERE display_name LIKE '{$search_word}'
)
) ";
}
}
}
return $search;
}
add_filter('posts_search','custom_search', 10, 2);

なよいちゃん
これで意図した結果にフリーワード検索ができると思います!
この記事への質問・コメントはこちら