デフォルトの投稿タイプの投稿(投稿タイプ:post
)とカスタム投稿タイプの投稿(投稿タイプ:cpt
)があります。後者には分類法があります(cpt_tag
)。
自分のフロントページに、デフォルトの投稿タイプの投稿(フィルタなし)、、およびいくつかのcpt
投稿タイプの投稿を、cpt_tag
がある場合にのみ表示します。
コードは次のとおりです。
add_action( 'pre_get_posts', 'get_posts_plus_cpt_with_certain_tag' );
function get_posts_plus_cpt_with_certain_tag( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$taxquery = array(
array(
'taxonomy' => 'cpt_tag',
'field' => 'term_id',
'terms' => 27
)
);
$query->set( 'tax_query', $taxquery );
$query->set( 'post_type', array( 'post', 'cpt' ) );
}
}
問題は$query->set( 'tax_query', $taxquery );
がcpt
投稿だけでなくpost
投稿にも適用されることです。 cpt
投稿をフィルタリングし、post
投稿をフィルタリングせずにtax_query
を使用するにはどうすればよいですか。
任意の助けがいただければ幸いです。ありがとうございます。
(これは 私の以前の質問 の明確化されたバージョンです。)
理解できるように、cpt_tag
はカスタム投稿タイプcpt
にのみ割り当てられます。これにより、作業がはるかに簡単になり、複雑さが軽減されます。 2つのクエリは必要なく、何もマージする必要はありません
計画は次のとおりです。
cpt
投稿タイプからホームページに表示する必要がある用語を知る必要があります
get_terms()
およびexclude
パラメーターを使用して、cpt
投稿タイプから投稿を表示するために必要な用語を除外します。 get_terms()
から返される配列には、表示したくないすべての用語が保持されます。また、fields
パラメーターをids
に設定して、用語IDの配列を取得します。
この配列は、tax_query
のpre_get_posts
に渡されます。これは除外する必要がある用語なので、operator
パラメーターをNOT IN
に設定して、これらの用語を含む投稿を除外します
この作業を行うには、コードを少し調整するだけです
ここに例があります
add_action( 'pre_get_posts', 'get_posts_plus_cpt_with_certain_tag' );
function get_posts_plus_cpt_with_certain_tag( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
/*
* Change 110 to the term id you need to display posts from from cpt post type
*/
$terms = get_terms( 'cpt_tag', array( 'exclude' => 110, 'fields' => 'ids' ) );
if ( $terms && !is_wp_error( $terms ) ) {
$taxquery = array(
array(
'taxonomy' => 'cpt_tag',
'field' => 'term_id',
'terms' => $terms,
'operator' => 'NOT IN'
)
);
$query->set('tax_query', $taxquery);
}
$query->set( 'post_type', array( 'post', 'cpt' ) );
}
}
私は安全性を含めませんでしたshould最初にget_terms
から結果を得るかどうかを使用する前にチェックしてください。これをコードに含めました
上記のソリューションは機能しますが、コメントで指摘されているように小さな不具合があります
...
cpt_tag
sをまったく持たないcpt
投稿タイプの投稿がある場合、tax_query
はそれらを除外せず、少なくとも1つのcpt_tag
を持つcpt
投稿タイプの投稿のみを除外します...
問題は、通常の投稿タイプpost
がデフォルトで割り当てられたuncategorized
という用語を持っているのと同じように、用語が割り当てられていない場合、デフォルトでカスタム投稿タイプの投稿にデフォルトの用語が割り当てられていないという事実で発生します用語がそれに割り当てられます
用語が割り当てられていない場合は用語との関係がないため、カスタム投稿タイプの投稿はwp_term_relationships
テーブルに表示されず、通常のtax_query
には表示されません
この問題を回避するには、元のワークフローをわずかに変更する必要があります。この問題に取り組む方法は次のとおりです
post
投稿タイプに割り当てられているすべての用語を取得します。デフォルトでは、post
投稿タイプのすべての投稿には、この動作が他の抜本的なコードによって変更されない限り、少なくとも1つの用語が割り当てられます。したがって、ここでは99.999%安全です。
前と同じ戦略を使用しますが、少し変更します。 fields
パラメーターをids
に設定したget_terms()
を引き続き使用しますが、ここではすべての用語を取得します。 category
投稿タイプにデフォルトのビルドイン分類法post
を使用していると仮定します。
cpt_tag
のincludeに必要な用語IDをtax_query
に渡すだけで、ここでは特別なことはできません。
relation
タクソノミーのすべての用語を持つ投稿が必要なため、OR
パラメーターをcategory
に設定することを忘れないでくださいまたはcpt_tag
タクソノミーの特定の用語を持つすべての投稿。 relation
パラメーターを省略すると、デフォルトでAND
になります。これは、category
タクソノミーに用語を持つ投稿を検索するため、クエリに失敗しますおよびcpt_tag
タクソノミー
それをコードに入れましょう:
(再び110
の用語に用語ID cpt_tag
を使用しますが、それに応じて変更します)
add_action( 'pre_get_posts', 'get_posts_plus_cpt_with_certain_tag' );
function get_posts_plus_cpt_with_certain_tag( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
/*
* Change 110 to the term id you need to display posts from from cpt post type
*/
$terms = get_terms( 'category', array( 'fields' => 'ids' ) );
if ( $terms && !is_wp_error( $terms ) ) {
$taxquery = array(
'relation' => 'OR',
array( // Includes all terms (categories) for post post type
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => $terms,
),
array( // Include the terms you need to display from cpt_tag
'taxonomy' => 'cpt_tag',
'field' => 'term_id',
'terms' => array( 110 ),
),
);
$query->set('tax_query', $taxquery);
}
$query->set( 'post_type', array( 'post', 'cpt' ) );
}
}