web-dev-qa-db-fra.com

Où devrait-on réinitialiser postdata?

J'ai cherché cela dans le Q & A mais je n'ai pas pu le trouver. Lorsque je lis les réponses sur tout le site, je vois que wp_reset_postdata() est placé dans plusieurs zones avec la condition have_posts() et en dehors de la condition, tous ensemble. Quand je lis la documentation sur wp_reset_postdata() tout ce qui est écrit est:

Après avoir parcouru une requête distincte, cette fonction restaure le $ post global à la publication actuelle de la requête principale.

avec un extrait de:

<?php
// example args
$args = array( 'posts_per_page' => 3 );

// the query
$the_query = new WP_Query( $args );
?>

<?php if ( $the_query->have_posts() ) : ?>

    <!-- start of the secondary loop -->
    <?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
        <?php the_title(); ?>
        <?php the_excerpt(); ?>
    <?php endwhile; ?>
    <!-- end of the secondary loop -->

    <!-- put pagination functions here -->

    <!-- reset the main query loop -->
    <?php wp_reset_postdata(); ?>

<?php else:  ?>

    <p><?php _e( 'Sorry, no posts matched your criteria.' ); ?></p>

<?php endif; ?>

mais quand je fais référence à d'autres moyens, tels que " Comment corriger la pagination pour les boucles personnalisées? " c'est après le conditionnel:

// Output custom query loop
if ( $custom_query->have_posts() ) :
    while ( $custom_query->have_posts() ) :
        $custom_query->the_post();
        // Loop output goes here
    endwhile;
endif;
// Reset postdata
wp_reset_postdata();

Ne serait-il pas approprié de l'avoir après et pas dans la condition have_posts() car, si vous utilisez une instruction else, les arguments ne sont pas réinitialisés si vous n'avez pas de publications. Ma question est donc la suivante: où wp_reset_postdata() devrait-il aller?

Version courte:

Comme l'a dit Tom J Nowell,

Vous ne devriez pas nettoyer s'il n'y a rien à nettoyer

Version longue:

Cependant, si vous mettez wp_reset_postdata() après (ou à l’extérieur) de la boucle, cela fonctionnera parfaitement. J'ai utilisé la fonction dans différents scénarios, notamment:

dynamic_sidebar( 'main-sidebar' );
wp_reset_postdata();

La raison était que certains widgets interrogeaient les publications sans se nettoyer.

Gardez simplement à l'esprit la requête que vous souhaitez réinitialiser. Dans l'exemple de Tom, peu importe si wp_reset_postdata se trouve dans l'instruction if ou non, une fois appelé, vous aurez des problèmes car il reviendra directement à la publication principale au lieu de la boucle personnalisée parente.

La fonction demande alors à un objet WP_Query de restaurer la publication actuelle dans la portée globale. Puisqu'il s'agit d'une fonction au lieu d'une méthode, il ne fonctionne qu'avec un seul objet: l'instance globale $wp_query de l'objet WP_Query.

Si vous avez des boucles personnalisées, dans lesquelles vous utilisez un WP_Query nouvellement généré, vous devez utiliser la méthode reset_postdata de cette requête:

$pages = new WP_Query( 'post_type=page' );
while( $pages->have_posts() ) {
    $pages->the_post();

    // Page title
    echo '<h1>'; the_title();  echo '</h1>';

    $books = new WP_Query( 'post_type=book&...' );
    if( $books->have_posts() ) {
        while( $books->have_posts() ) {
            $books->the_post();

            // Book title
            echo '<li>'; the_title(); echo '</li>';
        }

        // Don't go back to the global post, go back to the "page"
        // wp_reset_postdata();
        $pages->reset_postdata();
    }

    // Page content
    the_content();
}

// Finally, reset the main query
wp_reset_postdata();

J'espère que ça résume :)

3

Vous l'avez fait correctement! C'est l'exemple qui ne va pas . Malheureusement, presque tous les exemples de requêtes ont ce problème

Normalement, le placer après le conditionnel n'a aucun effet néfaste, mais lors de l'imbrication de boucles, cela pourrait poser problème dans les cas Edge. Pour 99,9% des cas d'utilisation, ce n'est pas un problème.

En le mettant dans la condition, vous vous êtes assuré que les données postales ne sont réinitialisées que si elles ont été modifiées.

Considérez ce cas Edge:

while( have_posts() ) {
    the_post();
    ... stuff...
    $q = new WP_Query( $args );
    if ( $q->have_posts() ) {
        while( $q->have_posts() ) {
            $q->the_post();
            the_title();
            $related_posts = new WP_Query( $args2 );
            if ( $related_posts->have_posts() ) {
                while( $related_posts->have_posts() ) {
                    $related_posts->the_post();
                    //
                }
            }
            wp_reset_postdata();

            the_content();
        }
    }
    wp_reset_postdata();
}

Ici, nous faisons une boucle imbriquée pour récupérer les publications associées, mais notez ce qui se passe si aucune publication associée n'est trouvée et que $related_posts->have_posts() renvoie false, les données postales sont réinitialisées sur celles de la boucle principale et vous obtenez le contenu de la publication de requêtes principales, et non celle de la requête $q

4
Tom J Nowell

Normalement, je l'utilise en dehors de l'instruction if($query->have_posts()). De cette façon, vous pouvez vous assurer que même s'il n'y a pas de message, la requête sera réinitialisée. Je n'ai aucun problème en le plaçant après (et à l'extérieur) de la déclaration if($query->have_posts()).

0
Hossein