D'abord le code:
function itsme_better_editions( $query ) {
if ( $query->is_category() && $query->is_main_query() ) {
$query->set( 'post_type', array( 'post' ) );
// Get current tax query
$tax_query = $query->get( 'tax_query' );
$tax_query['relation'] = 'OR';
$tax_query[] = array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'intl',
'operator' => 'IN'
);
$query->set( 'tax_query', $tax_query );
}
return $query;
}
add_filter( 'pre_get_posts', 'itsme_better_editions' );
Tout me semble correct, sauf que $query->get( 'tax_query' );
semble renvoyer un tableau vide ou non, c’est-à-dire que la condition suivante renvoie true
:
if( !empty($tax_query) || is_array($tax_query) ) {
// whatever
}
C'est casser des trucs, j'ai réalisé plus tard .
Les bons messages sont affichés dans l'archive, c.-à-d. Les messages appartenant à la catégorie actuelle OR sont classés dans la catégorie 'International (intl)'. C'est ce que je veux.
Mais le terme objet désigne la catégorie 'intl' (il en va de même dans les archives de balises; au lieu du terme objet désignant la balise actuelle, il pointe vers la catégorie 'intl'). Par exemple, si je visite les archives de la catégorie 'UK (uk)', le message 'International' au lieu de 'UK'.
Ce n'est qu'un des problèmes que j'ai remarqués jusqu'à présent. Je ne sais pas quoi d'autre est cassé.
Quel est le problème avec la fonction?
PS: Et comme $query->get( 'tax_query' );
retournait un tableau vide ou non, je devais le remplir manuellement de la manière suivante:
/*
* Show posts assigned to 'International (intl)' Edition
* in all editions.
*/
function itsme_better_editions( $query ) {
if( $query->is_category() && $query->is_main_query() ) {
$query->set( 'post_type', array( 'post' ) );
// NOT WORKING!!!
//$tax_query = $query->get( 'tax_query' );
// Equivalent of original `$tax_query` START.
$get_original_category = get_query_var( 'category_name' );
$original_category = get_term_by( 'slug', $get_original_category, 'category' );
if( $original_category && !is_wp_error( $original_category ) ) {
$itsme_original_category = $get_original_category;
}
$tax_query[] = array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $original_category,
'operator' => 'IN'
);
// Equivalent of original `$tax_query` END.
$tax_query['relation'] = 'OR';
$tax_query[] = array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'intl',
'operator' => 'IN'
);
$query->set( 'tax_query', $tax_query );
}
return $query;
}
add_filter( 'pre_get_posts', 'itsme_better_editions' );
OU remplacez simplement la requête comme suit:
/*
* Show posts assigned to 'International (intl)' Edition
* in all editions.
*/
function itsme_better_editions( $query ) {
if( $query->is_category() && $query->is_main_query() ) {
// Get original/actual category of the category archive
$get_original_category = get_query_var( 'category_name' );
$original_category = get_term_by( 'slug', $get_original_category, 'category' );
if( $original_category && !is_wp_error( $original_category ) ) {
$itsme_original_category = $get_original_category;
}
if( isset($itsme_original_category) ) {
$query->set( 'post_type', array( 'post' ) );
$query->set( "category_name", "{$itsme_original_category}, intl" );
}
}
}
add_action( 'pre_get_posts', 'itsme_better_editions' );
Cela fonctionne, mais pourquoi devrais-je le faire de cette façon? $tax_query = $query->get( 'tax_query' );
n'est-il pas censé renvoyer le tax_query
d'origine?
1. Créez deux catégories: UK (uk) et International (intl). Créez 2 messages et attribuez-les à 'UK' uniquement; 1 sous 'International' seulement.
Maintenant, example.com/category/uk/
montre 2 posts; et example.com/category/intl/
montre 1.
2. Ajoutez maintenant la première fonction (premier bloc de code) dans le fichier functions.php de votre thème et visitez example.com/category/uk/
. Vous verrez que le nom de la catégorie de la page (<?php single_cat_title(); ?>
) est indiqué par 'International'. Pourquoi? Si je ne me trompe pas, car $ query-> get ('tax_query'); semble retourner vide, pas un tableau.
3. Remplacez la fonction dans functions.php par la deuxième ou la troisième fonction ci-dessus. Maintenant, tout devrait fonctionner comme prévu.
PS: Oui, je me suis testé avec le thème par défaut (vingt-treize) et il persiste. Donc, vous seriez capable de reproduire le problème parfaitement.
Autant que je sache, $query->get
pour la requête principale fonctionne uniquement avec des vars de requête publics, c'est-à-dire des vars pouvant être déclenchés via une URL, mais rien n'empêche d'accéder directement à la propriété tax_query
de la requête, mais notez que c'est un objet, une instance de WP_Tax_Query
et les arguments de taxonomie actuellement recherchés se trouvent dans la propriété queries
de cet objet.
En accédant à cette propriété, vous évitez d'exécuter une autre requête avec get_term_by
dans votre fonction. Comme effet secondaire, single_cat_title
affichera le titre correct:
function itsme_better_editions( $query ) {
if ( $query->is_category() && $query->is_main_query() ) {
$query->set( 'post_type', array( 'post' ) );
$tax_query_obj = clone $query->tax_query;
$tax_query_obj->queries[] = array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'intl',
'operator' => 'IN'
);
$tax_query = array('relation' => 'OR');
foreach ( $tax_query_obj->queries as $q ) {
$tax_query[] = $q;
}
$query->set('tax_query', $tax_query);
}
}
add_action( 'pre_get_posts', 'itsme_better_editions' );
Notez que vous utilisez également le filtre sur les requêtes de l'administrateur, si ce n'est pas ce que vous souhaitez, ajoutez && ! is_admin()
dans la première if
conditionnelle dans la fonction.
PS: un conseil: lorsque vous utilisez 'pre_get_posts'
, vous pouvez utiliser add_action
au lieu de add_filter
et ne rien renvoyer, car la requête est transmise en tant que référence.
$tax_query = $query->get( 'tax_query' );
retournera l'original tax_query
s'il en passe un dans la requête. Par exemple:
function itsme_better_editions( $query ) {
$query->set( 'post_type', array( 'post' ) );
// Get current tax query
$tax_query = $query->get( 'tax_query' );
var_dump($tax_query); die;
}
add_action( 'pre_get_posts', 'itsme_better_editions' );
$t = new WP_Query(
array(
'post_type' => 'post',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => 'intl',
'operator' => 'IN'
)
)
)
);
Toutefois, si vous videz $wp_query
sur une archive de catégorie ou effectuez un test similaire sur la requête principale, il n'y a pas de tax_query
comme vous l'avez déjà découvert. En effet, pour certaines des requêtes par défaut, l’objet WP_Query
, construit ce tax_query
à partir d’autres paramètres de requête longtemps après que pre_get_posts
a été exécuté . C'est pourquoi $tax_query = $query->get( 'tax_query' );
est vide.