基本的なフィルターフックなどで対応できるパターン。
SQL文を書く前に、本当にその実装でいいのかよく考えよう。
カスタム投稿タイプ
public
の引数が true
(デフォルト)であれば、検索ロジック周りであれこれする必要なし。
逆に公開しても検索の対象外とする場合は exclude_from_search
の引数を true
にする。
特定の条件を検索対象「外」とする
基本、上記のやり方でいいのですが、カテゴリーやタクソノミーなど条件を細かくしたい場合は pre_get_posts
でやるのが一番簡単。
例は「特定のカテゴリーに属する投稿は検索対象にしない」
<?php
function search_filter($query) {
if ( is_admin() || ! $query->is_main_query() )
return;
if ( $query->is_search() ) {
$query->set( 'category__not_in', array( 1 ) );
return;
}
}
add_action( 'pre_get_posts','search_filter' );
特定のカスタム投稿タイプを対象とした検索窓を別途作る
例えばFAQだけ検索する検索窓。
-
form
のaction
はhome_url( '/' )
<input type="hidden" name="post_type[]" value="{カスタム投稿タイプのスラッグ}" />
試しにブラウザで直接 http://example.com/?s=test&post_type[]=faq
とすると結果がわかるよ
<form role="search" method="get" class="search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
<input type="hidden" name="post_type[]" value="faq" />
<label>
<span class="screen-reader-text">Search FAQ for:</span>
<input type="search" class="search-field" placeholder="Search FAQ" value="<?php the_search_query(); ?>" name="s" title="Search FAQ" />
</label>
<input type="submit" class="search-submit" value="Search" />
</form>
検索結果を通常の検索結果用テンプレートと別にする場合はtemplate_include
で。
https://codex.wordpress.org/Plugin_API/Filter_Reference/template_include
function my_custom_search_template( $template ) {
if ( is_search() ) {
// 表示する投稿タイプを取得
$post_types = get_query_var( 'post_type' );
// search-{$post_type}.php の読み込みルールを追加
foreach ( (array) $post_types as $post_type )
$templates[] = "search-{$post_type}.php";
$templates[] = 'search.php';
$template = get_query_template( 'search', $templates );
}
return $template;
}
add_filter( 'template_include', 'my_custom_search_template' );
絞り込み検索したい
これもプラグイン使っったほうが楽。
とは言え、 http://example.com/?s=test&post_type[]=faq&category_name=cat-a
となれば絞込はできるので、前述のフォームをカスタマイズして行けば自作でも可能。
カスタムフィールド・・・
デフォルトでは検索対象「外」なのでこれが一番厄介。
仕様の見直し
本当にカスタムフィールドで実装するのか。カスタムタクソノミーなら検索対象になりつつ「アーカイブを作らない」事もできるので考慮すること
プラグイン使う
カスタムフィールドも対象にするには最終的にSQL文を発行しないといけないので、いろいろ不安ならプラグインでサクッと実装したほうが楽。