私は検索結果からpages
を除外したいと思い、それをする多くの方法を見つけました、そしてなぜ!is_admin()
またはis_main_query()
を使うか、そしてどちらがより良いのか疑問に思いました。
add_filter('pre_get_posts','search_filter');
function search_filter($query) {
if ($query->is_search) {
$query->set('post_type', 'post');
}
return $query;
}
add_filter('pre_get_posts','search_filter');
function search_filter($query) {
if ( !is_admin() && $query->is_search) {
$query->set('post_type', 'post');
}
return $query;
}
add_action('pre_get_posts','search_filter');
function search_filter($query) {
if ( !is_admin() && $query->is_main_query() ) {
if ($query->is_search) {
$query->set('post_type', 'post');
}
}
}
以下を使用する場合に注意してください。
$query->set( 'post_type', 'post' );
page
投稿タイプだけでなく、すべての検索可能な投稿タイプをオーバーライドします。
場合によってはそれで十分かもしれませんが、私たちのニーズに合ったいくつかのpre_get_posts
スニペットを使用して完了しました。
ただし、そのようにハード修正したくない場合があります。ここでは、そのようなシナリオについて説明します。
register_post_type_argsフィルターを使用します。
投稿タイプが指定されていない場合、WP_Query
検索は検索可能な投稿タイプを使用します つまり :
$in_search_post_types = get_post_types( array('exclude_from_search' => false) );
投稿タイプを登録するときに、exclude_from_search
パラメーターをfalseに設定して、検索から除外できます。
page
投稿タイプのセットアップ用に次のように変更できます。
add_filter( 'register_post_type_args', function( $args, $name )
{
// Target 'page' post type
if( 'page' === $name )
$args['exclude_from_search'] = true;
return $args;
}, 10, 2 );
register_post_type()
の詳細 ここ 。
例
上記のフィルタリングを使用して、ページ投稿タイプが検索から除外される例は次のとおりです。
フロントエンドでのメインクエリ検索
https://example.tld?s=testing
次のようなセカンダリクエリ:
$query = new WP_Query( [ 's' => 'testing' ] );
次のようなセカンダリクエリ:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => 'any' ] );
事前設定された投稿タイプのクエリに関する注意:
次のような投稿タイプが固定されている場合を考えてみましょう。
$query = new WP_Query( [ 's' => 'testing', 'post_type' => [ 'page', 'post'] ] );
投稿タイプが何らかの配列$post_type
によって設定されている場合、'page'
をフィルタリングして、
if( is_array( $post_type ) && count( $post_type ) > 1 )
{
$post_type = array_filter(
$post_type,
function( $item ) { return 'page' !== $item; }
);
}
その配列に直接アクセスできない場合は、たとえばpre_get_posts
は、WP_Query
のget
/set
メソッドを使用して、投稿タイプの配列から「ページ」を削除します。フロントエンドのメイン検索クエリの例を次に示します。
add_action( 'pre_get_posts', function search_filter( \WP_Query $query )
{
if( ! $query->is_search() || ! $query->is_main_query() || ! is_admin() )
return;
$post_type = $query->get( 'post_type' );
if( is_array( $post_type ) && count( $post_type ) > 1 )
{
$post_type = array_filter(
$post_type,
function( $item ) { return 'page' !== $item; }
);
$query->set('post_type', $post_type );
}
} );
ここで配列数> 1を確認したのはなぜですか?
これは、次のような例から'page'
を削除することに注意する必要があるためです。
$query = new WP_Query( [ 's' => 'testing', 'post_type' => [ 'page' ] ] );
$query = new WP_Query( [ 's' => 'testing', 'post_type' => 'page' ] );
投稿タイプの場合、空の配列または空の文字列として:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => [] ] );
$query = new WP_Query( [ 's' => 'testing', 'post_type' => '' ] );
'post'
投稿タイプにフォールバックします。
ご了承ください:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => 'page, post' ] );
結果の投稿タイプは'pagepost'
になるため、サポートされていません。
WP_Query
オブジェクトに直接アクセスできないこれらの場合、検索WHEREクエリ部分で'post__in' => []
または1=0
などのトリックを使用してクエリを停止するか、さらにはposts_pre_query
フィルターまたはより高度な方法を使用します。このサイトには、それに関する多くの答えがあります。 This および this は、今思い出したものです。
null
ケース:
$query = new WP_Query( [ 's' => 'testing', 'post_type' => null ] );
'any'
投稿タイプにフォールバックします。
それが役に立てば幸い!
PS:
両方があるため、スニペットの不整合にも注意してください
add_filter('pre_get_posts','search_filter');
そして
add_action('pre_get_posts','search_filter');
これはactionと見なされますが、アクションはフィルターのように背後でラップされるため、違いはありません。
pre_get_posts
はフロントエンドだけでなくadminでも実行されます。これを使用すると、adminユーザーに表示される投稿とフロントエンドの結果をフィルタリングできます。 ! is_admin()
を追加することはそのコードがフロントエンドだけに影響することを確実にするでしょう。
is_main_query()
はあなたが投稿のクエリにのみ影響を与えていることを保証します、例えばナビゲーションバーのメニューアイテムやサイドバーの投稿のリストには影響しません。それを使うことをお勧めします。
これが明らかではないかどうか私に知らせてください、