web-dev-qa-db-fra.com

Je suis incapable de réinitialiser une requête correctement

J'ai une page d'archive de taxonomie personnalisée appelée 'taxonomy-teacher.php' où j'affiche la méta de l'enseignant (titre et description), puis une boucle pour toutes les discussions de l'enseignant (fichiers audio), qui ont un type de message personnalisé 'audiotalk'. "enseignant" est une taxonomie non-hiérarchique pour "audiotalk". Tout fonctionne très bien.

Les audiotalk ont ​​également une taxonomie héréditaire appelée "audiotalk-categories" afin que les internautes puissent les rechercher ailleurs sur le site. Mais sur cette page, je n'ai pas besoin de ces catégories.

Voici le problème: j'inclus un fichier au bas de ce modèle qui affiche les "livres liés". Dans cet include, il a sa propre boucle qui interroge d'abord la taxonomie pour déterminer ce qu'il faut afficher. Je veux qu'il montre les livres liés à la taxonomie des "enseignants", mais il montre en fait les livres liés aux "catégories d'audiotalk". J'ai donc essayé de réinitialiser cette boucle audio avec toutes les méthodes que je peux trouver en ligne et rien ne fonctionne.

Voici mon code (il a une de mes tentatives):

<div class="main-col">
    <div class="teacher-header clearfix">
        <h1>Teacher : <?php single_cat_title(); ?></h1>
        <?php echo tag_description(); ?>
    </div>

    <h3><?php single_cat_title(); ?>'s Bodhi Talks:</h3>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); if( get_field('in_sub') == 'yes' ) : ?>
    <div class="list-item">
        <a href="<?php the_permalink(); ?>" class="list-link"><?php the_title(); ?></a>
        <div class="desc">
    <?php if( get_field('talk_description') ) : ?>
            <p><?php the_field('talk_description'); ?></p>
        </div>
        <div class="meta">
    <?php endif; ?>
            <a href="<?php the_permalink(); ?>" class="listen-link">Listen Now &raquo;</a>
        </div>
    </div>
<?php endif; endwhile; endif; wp_reset_query(); ?>

<?php get_template_part('template-related-products'); ?>

</div>

J'ai aussi essayé wp_reset_postdata () et j'ai essayé de placer wp_reset_postdata () et wp_reset_query () à différents endroits dans les ifs et les whiles.

Voici le code pour template-related-products.php. Cela fonctionne parfaitement partout ailleurs, il est inclus, mais je me rends compte que la faute pourrait être ici aussi:

<?php // Suggested Books
    if ( is_post_type_archive( 'teacher' ) ) :
        $top_taxonomy = 'teacher';
    else :
        $top_taxonomy = 'audiotalk-category';
    endif;

    $terms_list = wp_get_post_terms( $post->ID, $top_taxonomy, array( 'fields' => 'all' ) );

    foreach ($terms_list as $term) :
        $term_id = $term->term_id;
        $taxonomy = $term->taxonomy;
        $tax_query[] = array (
            'taxonomy' => $taxonomy,
            'field' => 'term_id',
            'terms' => $term_id,
        );
    endforeach;

    $tax_query['relation'] = 'OR';

    if ( is_post_type_archive( 'teacher' ) ) :
        $args = array(
            'post_type' => 'related_product',
            'posts_per_page' => 3,
            'orderby' => 'Rand',
            'meta_query' => array(
                array(
                    'key' => 'related_product_type',
                    'compare' => '==',
                    'value' => 'book'
                ),
                array(
                    'key' => 'associated_audio_talk_teacher',
                    'compare' => 'LIKE',
                    'value' => $term_id
                )
            )
        );
    else :
        $args = array (
            'post_type' => 'related_product',
            'posts_per_page' => 3,
            'orderby' => 'Rand',
            'order' => 'ASC',
            'meta_query' => array (
                array ( 
                    'key' => 'related_product_type',
                    'compare' => '=',
                    'value' => 'book'
                )
            ),
            'tax_query' => $tax_query,
        );
    endif;

    $rp_query = new WP_Query( $args );
?>
<?php if( $rp_query->have_posts() ): ?>
    <h3>Suggested Reading</h3>
    <ul class="related-products">
<?php while( $rp_query->have_posts() ) : $rp_query->the_post(); ?>
        <li class="book-item">
            <div class="prod-img">
                <a href="<?php echo get_field('related_product_store_link'); ?>"><img src="<?php echo get_field('related_product_image'); ?>" alt="<?php echo get_field('related_product_title'); ?>"></a>
            </div>
            <div class="item-deets">
                <h3><a href="<?php echo get_field('related_product_store_link'); ?>"><?php echo get_field('related_product_title'); ?></a></h3>
                <span class="author"><?php echo get_field('related_book_author'); ?></span>
            </div>
        </li>
<?php endwhile; ?>
    </ul>
<?php endif; wp_reset_query(); ?>

Si j'écho $ top_taxonomy, il dit toujours 'audiotalk-category' et si print_r ($ terms_list), il affiche la taxonomie de cette conversation audio, pas celle d'origine du modèle. Toute aide serait appréciée.

1
semidivine

wp_reset_query sert à nettoyer après un appel query_posts; vous n'avez pas besoin de l'appeler après une boucle de publication standard, uniquement si vous utilisez query_posts. Puisque vous ne devez jamais utiliser query_posts pour récupérer des publications dans la base de données, vous ne devez jamais utiliser cette fonction.

Mais comment puis-je nettoyer après la boucle principale?

Vous ne le faites pas, ceci est un exemple d'une boucle complète de publication principale:

if ( have_posts() ) {
    while ( have_posts() ) {
        the_post();
        // display content
    }
} else {
    // none found
}

Qu'en est-il de WP_Query ou get_posts?

Il existe une fonction similaire et plus utile nommée wp_reset_postdata. Cette fonction nettoie après ces fonctions:

  • WP_Query::the_post
  • setup_postdata

Ainsi, un exemple de boucle de publication WP_Query devrait ressembler à ceci:

$q = new WP_Query( [ ... ] );
if ( $q->have_posts() ) {
    while ( $q->have_posts() ) {
        $q->the_post();
        // display content
    }
    wp_reset_postdata();
} else {
    // none found
}

Notez que j'ai appelé wp_reset_postdata après la boucle while, mais à l'intérieur de l'instruction if et non après. Ne réinitialisez les données postérieures que s'il y a quelque chose à nettoyer

Et si j'ai besoin de passer outre la boucle?

Utilisez le filtre pre_get_posts pour modifier la boucle principale. Ne créez pas de nouvelle requête de remplacement.

Qu'en est-il de get_posts?

Si vous ne définissez jamais les données postérieures, vous ne devez jamais les réinitialiser.

1
Tom J Nowell