web-dev-qa-db-fra.com

Inclure et exclure des taxonomies d'archives et de flux à l'aide de 'pre_get_posts'

Qu'est-ce que j'essaie de faire?

Mon blog utilise une taxonomie personnalisée appelée edition avec des termes tels que us-canada (6), eu (7) et india (8) - slug (ID).

Je veux m'assurer que les posts ne sont affectés à aucune édition particulière soient affichés sous tous les termes (c'est-à-dire si un post n'est pas attribué à usa, europe ou india, il sera affiché dans les archives pages de tous ces termes).

Qu'est-ce que j'ai essayé?

Voici l'exemple de code relatif à l'un des termes, qui devrait vous donner une idée de ce que j'essaie de faire et de ce que je ferais de travers.

add_filter('pre_get_posts','better_editions_archive');

function better_editions_archive($query) {

    if ( $query->is_tax( 'edition', 6 ) && $query->is_main_query() ) {
        $query->set( 'post_type', array( 'post' ) );

        $query->set( 'tax_query',
            array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => array( 1, 2, 4, 5 )
                ),
                array(
                    'taxonomy' => 'edition',
                    'field' => 'id',
                    'terms' => array( 7, 8 ),
                    'operator' => 'NOT IN'
                )
            )
        );
    }

    return $query;
}

Qu'est-ce qui ne va pas? Le code mentionné ci-dessus ne fonctionne pas (les autres que j'ai essayés: code-1 , code-2 ), cela ne change rien. Il n'y a pas d'erreur de débogage non plus.

Alors, que pourrais-je faire de mal?

ÉGALEMENT, afin de m'assurer que les modifications s'appliquent également aux flux de ces termes, j'ai remplacé la ligne correspondante dans le code susmentionné par la suivante:

function better_editions_archive($query) {

    if ( ( $query->is_tax( 'edition', 6 ) && $query->is_main_query() ) || ( $query->is_feed() && $query->is_tax( 'edition', 6 ) ) ) {

Mais cela commence à rediriger les flux de termes vers leurs archives. C'est-à-dire que, lorsque la fonction est en place, example.com/edition/usa/feed/ redirige vers example.com/edition/usa/.

Encore une fois, je n'ai aucune idée de ce que je ferais de mal.

UPDATE: Qu'est-ce qui a fonctionné pour moi? (Mais...)

add_filter( 'pre_get_posts', 'better_editions_archive' );

function better_editions_archive( $query ) {
    if ( $query->is_tax( 'edition', 6 ) && $query->is_main_query() ) {

        $args = array(
            'post_type' => 'post',

            'tax_query' => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => array( 1, 2, 4, 5 )
                ),
                array(
                    'taxonomy' => 'edition',
                    'field' => 'id',
                    'terms' => array( 7, 8 ),
                    'operator' => 'NOT IN'
                )
            )
        );

        $query->query_vars = $args;
    }

    return $query;
}

Cela fonctionne, mais le problème, c’est que j’ai eu une discussion approfondie avec un développeur WordPress averti, et il m’a dit ceci (vous pouvez suivre la conversation complète ici , mais elle est trop longue):

Et vous assignez ensuite ce tableau en tant que query_vars. Maintenant, le query_vars est un objet assez gros. Et vous écrasez les données et ajoutez simplement vos données personnalisées. Cela signifie que vous "désélectionnez" tout ce qui est ajouté par défaut.

Il a plutôt déconseillé d'utiliser cette solution et a opté pour la méthode $query->set();.

Mais comme vous pouvez le voir bien au-dessus, je ne pouvais pas faire fonctionner l’autre. Je suis donc ici pour voir si quelqu'un peut me dire ce que je fais mal, en termes moins techniques.

5
its_me

Je vais prendre un autre coup.

Les éléments suivants doivent modifier la requête principale, de manière à inclure dans sa boucle les publications appartenant à aucun terme de la taxonomie personnalisée Edition .

add_filter('pre_get_posts','better_editions_archive');

function better_editions_archive( $query ) {

    if ( $query->is_tax( 'edition' ) && $query->is_main_query() ) {
        $terms = get_terms( 'edition', array( 'fields' => 'ids' ) );
        $query->set( 'post_type', array( 'post' ) );
        $query->set( 'tax_query', array(
            'relation' => 'OR',
            array(
                'taxonomy' => 'edition',
                'field' => 'id',
                'terms' => $terms,
                'operator' => 'NOT IN'
            )
        ) );
    }

    return $query;
}
14
vancoder

Note to self: @ La réponse de vancoder est fondamentalement une meilleure version (& automatisée) de ceci:

add_filter('pre_get_posts','better_editions_archive');

function better_editions_archive($query) {

    if ( $query->is_tax( 'edition') && $query->is_main_query() ) {

        $query->set( 'post_type', array( 'post' ) );

        $query->set( 'tax_query',
            array(
                array(
                    'taxonomy' => 'edition',
                    'field' => 'id',
                    'terms' => array( 6, 7, 8 ),
                    'operator' => 'NOT IN'
                )
            )
        );

    }

    return $query;
}

(Signification du code) S'il s'agit de l'archive d'un terme appartenant à la taxonomie personnalisée 'edition', alors ...

  1. Le code ne perturbe pas la fonction par défaut des termes "pages d'archives", c'est-à-dire que les publications affectées à un terme de la taxonomie personnalisée "edition" seront (comme d'habitude) affichées dans les archives du terme correspondant.

  2. Mais si une publication n'est affectée à aucun des termes de la taxonomie donnée (voir 'terms' => array( 6, 7, 8 ) et 'operator' => 'NOT IN'), affichez-les dans les pages d'archive de tous les termes de la taxonomie personnalisée.

  3. Le code affecte également les flux desdits termes, et reflète donc le contenu des pages d'archives, ce dont j'ai besoin. Si vous ne souhaitez pas que les flux soient affectés, c’est-à-dire si vous souhaitez que les modifications s’appliquent uniquement aux pages d’archive, remplacez le IF par ceci:

    if ( $query->is_tax( 'edition') && $query->is_main_query() && ! $query->is_feed() ) {
    
1
its_me