web-dev-qa-db-fra.com

Utiliser pre_get_posts pour filtrer les publications

J'essaie de filtrer archive_research.php pour afficher uniquement les recherches avec status = current.

Dans functions.php:

add_action( 'pre_get_posts', 'only_current' );

function only_current( $query ) {
    if ( $query->is_main_query() ) {
        $args = array(
            'post_type' => 'research',
            'tax_query' => array(
                array(
                    'taxonomy' => 'status',
                    'field'    => 'slug',
                    'terms'    => 'current',
                ),
             ),
        );
        $query = new WP_Query( $args );
    }
}

Dans archive-research.php:

        // theloop
        if ( have_posts() ) : while ( have_posts() ) : the_post();
            // print title etc

Résultat: les archives de recherche affichent TOUTES les recherches.

J'ai essayé beaucoup de légères modifications de ceci. Par souci de lisibilité, je vais essayer de les résumer ici sans coller un tas de code redondant:

  • supprimer le tax_query .. même résultat (attendu)
  • changer le tax_query en un terme de taxonomie qui n'existe pas .. même résultat
  • en remplaçant $query = new WP_Query( $args ) par $query->set('meta_query', $args) ou $query->set($args) .. même résultat
  • en remplaçant have_posts() et the_post() dans archive-research par $wp_query->have_posts() et $wp_query->the_post() .. même résultat
  • ajout d'un appel à do_action('only_current') avant // theloop .. même résultat

Donc, le thème commun ici est que peu importe ce que je fais, j'obtiens le même résultat. Il doit y avoir une solution très évidente qui me manque, et j'apprécierais vraiment si quelqu'un pouvait le faire remarquer.

Dernière information de débogage qui pourrait être utile:

string (222) "SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1 = 1 AND wp_posts.post_type = 'research' ET (wp_posts.post_status = 'publier' OR wp_posts.post_status = 'private') wp_posts.post_date DESC LIMIT 0, 10 "

Ceci est le résultat de l'appel de echo var_dump($wp_query->request) avant // theloop

2
Kristina

Vous créez une nouvelle requête sans modifier celle qui existe.

La page de codex pre_get_posts comporte une note expliquant que l'argument $ query est passé par référence et que vous devez le modifier directement. Il n'est pas nécessaire de déclarer des valeurs globales ou des valeurs renvoyées. Mettez à jour votre fonction pour être:

add_action( 'pre_get_posts', 'only_current' );
function only_current( $query ) {

    if ( is_admin() ) {
        return;
    }

    if ( ! $query->is_main_query() ) {
        return;
    }

    if ( ! is_post_type_archive( 'research' ) ) {
        return;
    }

    $tax_query = array(
        array(
            'taxonomy' => 'status',
            'field'    => 'slug',
            'terms'    => 'current',
        ),
    );
    $query->set( 'tax_query', $tax_query );
}

Le filtre pre_get_posts s'applique également aux requêtes de l'administrateur. J'ai donc ajouté une autre instruction if pour vérifier que nous sommes au début du site.

J'ai également ajouté une déclaration pour vérifier que nous sommes sur la page d'archive research.

La fonction ci-dessus doit être placée dans votre fichier functions.php, ou dans un plugin spécifique au site. Le placer dans le fichier archive-research.php ne fonctionnera pas car la requête aura été exécutée au moment du chargement du modèle archive-research.php.

1
Andrew