> Wordpress > Wordpressの検索をプラグインなしでカスタマイズしてみる
Wordpressの検索をプラグインなしでカスタマイズしてみる

Wordpressの検索をプラグインなしでカスタマイズしてみる

Wordpressの検索では、デフォルトでは「タイトル」「本文」の文字列のみしか検索できません。
これを、「カスタムフィールド」「タグ・カテゴリーなどのタクソノミー」「ユーザー名」を検索対象に含めてみます。

プラグインでこれをしようとすると、いくつか候補が上がってきます。
中でも有名所でいうと「Search Everything」になると思いますが、残念なことに新規投稿公開時にエラーが発生するバグがあり、2021年10月時点でまだ対応がなされていません。
function.phpで対応するためには様々な解説記事があり、その中で使用させていただいたものにカスタマイズを加えたので紹介します。

/**
 * 検索にタイトル・本文以外にターム名・カスタムフィールド・ユーザー名をor検索にする
 *
 * @param Search   $search search.
 * @param Wp_query $wp_query search.
 * @return Search
 * */
function custom_search( $search, $wp_query ) {
    global $wpdb;
    // 検索画面でなければ戻る.
    if ( ! isset( $wp_query->query_vars ) ) {
        return $search;
    }

    if ( isset( $wp_query->query_vars['s'] ) ) {
        // カスタムフィールド・ターム名・ユーザー名を検索対象にする.
        $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 ) . '%';
                    $posts              = esc_sql( $wpdb->posts );
                    $users              = esc_sql( $wpdb->users );
                    $term_relationships = esc_sql( $wpdb->term_relationships );
                    $term_taxonomy      = esc_sql( $wpdb->term_taxonomy );
                    $terms              = esc_sql( $wpdb->terms );
                    $postmeta           = esc_sql( $wpdb->postmeta );
                    $search     .= " AND (
                        {$posts}.post_title LIKE '{$search_word}'
                        OR {$posts}.post_content LIKE '{$search_word}'
                        OR {$posts}.post_author IN (
                            SELECT distinct ID
                            FROM {$users}
                            WHERE display_name LIKE '{$search_word}'
                        )
                        OR {$posts}.ID IN (
                            SELECT distinct r.object_id
                            FROM {$term_relationships} AS r
                            INNER JOIN {$term_taxonomy} AS tt ON r.term_taxonomy_id = tt.term_taxonomy_id
                            INNER JOIN {$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 {$posts}.ID IN (
                            SELECT distinct p.post_id
                            FROM {$postmeta} AS p
                            WHERE p.meta_value LIKE '{$search_word}'
                        )
                    ) ";
                }
            }
        }
        return $search;
    }
}
add_filter( 'posts_search', 'custom_search', 10, 2 );

元の記事でも問題なく動きましたが、必要箇所にesc_sql()を追加しました。
何かあった時のため、エスケープ処理を施しておいて損は無いと思います。

参考サイト

デザイナーのタネあかし「WordPress のサイト内検索をプラグインなしでカスタマイズする方法」
https://taneakashi.ad-mk.com/wordpress-site-search-customize.html

この記事が気に入ったらシェアしてください

関連記事

Wordpressのカスタム投稿タイプで一覧・詳細画面を作らない方法

Wordpressのプラグイン「AddToAny Share Buttons」で任意の場所にシェアボタンを設置する方法

Wordpressのプラグイン「AddToAny Share Buttons」で任意の場所にシェアボタンを設置する方法

Wordpress Popular Postsでの表示内容をテーマ内でカスタマイズする方法

Wordpress Popular Postsでの表示内容をテーマ内でカスタマイズする方法

Wordpressの投稿からカテゴリーやタグを削除する方法

Wordpressの投稿からカテゴリーやタグを削除する方法

Wordpressで記事のIDから記事内の一番目にある画像を取得する関数

Wordpressで記事のIDから記事内の一番目にある画像を取得する関数

Wordpressのget_terms()で特定のカスタム投稿タイプの公開記事のみcountの対象にする方法

Wordpressのget_terms()で特定のカスタム投稿タイプの公開記事のみcountの対象にする方法

Comment Form

コメント投稿はこちらをクリックしてください
  • コメントを入力してください。
登録フォーム
Name
Mailaddress
URL
Message
Postkey
(スパム対策に、投稿キー を半角で入力してください。)