J'ai des publications de type publication par défaut (type de publication: post
) et des publications de type publication personnalisées (type de publication: cpt
). Ce dernier a une taxonomie (cpt_tag
).
Je voudrais afficher sur ma page d'accueil tous les articles de type d'article par défaut (non filtrés), et certains articles de type cpt
, uniquement s'ils ont un certain cpt_tag
.
Le code est:
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' ) );
}
}
Le problème est que $query->set( 'tax_query', $taxquery );
est appliqué non seulement aux articles cpt
, mais également aux articles post
. Comment utiliser tax_query
uniquement pour filtrer les publications cpt
et laisser les publications post
non filtrées?
Toute aide serait appréciée. Merci!
(Ceci est une version clarifiée de ma question précédente .)
Comme je peux le comprendre, cpt_tag
est uniquement affecté au type de publication personnalisé cpt
. Cela rend les choses beaucoup plus faciles et moins compliquées. Vous n'avez pas besoin de deux requêtes et vous n'avez rien à fusionner
Voici le plan:
Nous devons savoir quels termes vous devez afficher sur la page d'accueil à partir du type de message cpt
En utilisant get_terms()
et le paramètre exclude
, nous exclurons les termes nécessaires pour afficher les publications du type de publication cpt
. Le tableau retourné par get_terms()
contiendra tous les termes que nous ne voulons pas montrer. Nous allons également définir le paramètre fields
sur ids
afin d'obtenir un tableau d'identifiants de termes.
Ce tableau sera passé au tax_query
dans pre_get_posts
. Comme il s’agit de termes que nous devons exclure, nous allons définir le paramètre operator
sur NOT IN
pour exclure les publications contenant ces termes.
Vous n'avez besoin que d'ajustements mineurs à votre code pour que cela fonctionne
Voici un exemple
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' ) );
}
}
Je n’ai pas inclus la sécurité, vous devriez vérifier d’abord si vous obtenez des résultats de get_terms
avant de l’utiliser. J'ai inclus cela dans mon code maintenant
La solution ci-dessus fonctionne, mais il y a un petit problème, comme indiqué dans les commentaires
... si j'ai
cpt
publications de type post qui n'ont pas du toutcpt_tag
s, letax_query
ne les filtre pas, il filtre uniquement les publicationscpt
avec au moins uncpt_tag
...
Le problème provient du fait que les publications de type publication personnalisée par défaut ne sont pas affectées à un terme par défaut si aucun terme ne leur est attribué de la même manière que le type de publication normale post
se voit attribuer le terme uncategorized
par défaut lorsque aucun terme lui est attribué
Comme il n'y a pas de relation avec un terme si aucun terme ne lui est attribué, les publications de type publication personnalisées n'apparaissent pas dans la table wp_term_relationships
; elles n'apparaissent donc pas dans un tax_query
normal.
Pour résoudre ce problème, nous devons légèrement modifier notre flux de travail initial. Voici comment nous allons aborder ce problème
Obtenez tous les termes affectés au type d'article post
. Par défaut, au moins un terme est attribué à toutes les publications du type de publication post
à moins que ce problème ne soit modifié par un autre code radical. Nous sommes donc en sécurité à 99,999%.
Nous allons utiliser la même stratégie que précédemment mais avec une légère modification. Nous utiliserons toujours get_terms()
avec le paramètre fields
défini sur ids
, mais ici nous aurons tous les termes. Je suppose que vous utilisez la taxonomie intégrée par défaut category
pour le type de message post
.
Nous pouvons simplement simplement passer les identifiants de termes dont nous avons besoin pour inclure pour le cpt_tag
à notre tax_query
, rien de spécial ici
N'oubliez pas de définir le paramètre relation
sur OR
car nous avons besoin de publications avec tous les termes dans category
taxonomy ou toutes les publications qui ont le terme spécifique de la taxonomie cpt_tag
. Si vous omettez le paramètre relation
, la valeur par défaut est AND
, ce qui échouera à votre requête car elle recherchera les publications qui ont des termes ayant la taxonomie category
taxonomie et cpt_tag
taxonomy
Alors mettons cela dans le code:
( Je vais encore utiliser le terme id 110
pour le terme pour cpt_tag
, il suffit de changer en conséquence )
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' ) );
}
}