1

I have a custom taxonomy archive page called 'taxonomy-teacher.php' where I display teacher meta (title & description) and then I loop through all the teacher's talks (audio files), which have custom post type 'audiotalk'. 'teacher' is a non-heirarchical taxonomy for 'audiotalk'. Everything works great.

'audiotalk's also have a heirachical custom taxonomy called 'audiotalk-categories' so people can seach for them elsewhere on the site. But on this page I have no need for those categories.

Here's the problem: I am including a file at the bottom of this template that displays "related books". In that include it has its own loop that first queries the taxonomy to determine what to show. I want it to show books related to that 'teacher' taxonomy, but it's actually showing books related to the 'audiotalk-categories'. So I've been trying to reset that audiotalk loop with every method I can find online and nothing is working.

Here's my code (it has one of my attempts):

<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>

I also tried wp_reset_postdata() and I tried putting both wp_reset_postdata() and wp_reset_query() in different places in the ifs and whiles.

Here is the code for template-related-products.php. It works perfectly everywhere else it is included, but I realize the fault could be here as well:

<?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(); ?>

If I echo $top_taxonomy it always says 'audiotalk-category' and if I print_r($terms_list) it shows the taxonomy for that audio talk, not the original taxonomy for the template. Any help would be appreciated.

  • 3
    a taxonomy archive is not a post type archive, they are two different things. – Milo May 9 '17 at 21:16
  • So I should use is_tax()? – semidivine May 9 '17 at 23:58
  • If 'teacher' is a taxonomy and you are viewing a taxonomy archive, then yes, you should use is_tax to test for that condition. – Milo May 9 '17 at 23:59
  • Milo that's it, that was the issue. So glad I included the include code, I really thought that code was fine, because it worked in every other case. Thanks! – semidivine May 10 '17 at 19:19
1

wp_reset_query is for cleaning up after a query_posts call, you don't need to call it after a standard posts loop, only if you use query_posts. Since you should never use query_posts to fetch posts from the database, you should never use this function.

But How Do I Cleanup After The Main Loop?

You don't, this is an example of a full main post loop:

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

What About WP_Query or get_posts?

There's a similar and more useful function named wp_reset_postdata. This function cleans up after these functions:

  • WP_Query::the_post
  • setup_postdata

So an example of a WP_Query post loop should look like:

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

Notice that I called wp_reset_postdata after the while loop, but inside the if statement, not after it. Only reset postdata if there's something to clean up

And If I Need To Override The Loop?

Use the pre_get_posts filter to modify the main loop, don't create a new replacement query.

What About get_posts?

If you never set the postdata, then you never have to reset it.

  • Tom I tried just adding $q-> to my loop and it broke, returned nothing. I would need to set up a query correct? ie. $q = new WP_Query() – semidivine May 9 '17 at 23:51
  • Yes, I only used $q for my example, there's nothing 'magic' or 'special' about it other than that I couldn't be arsed typing $query when I wrote the answer. I've expanded my question to make it clearer – Tom J Nowell May 10 '17 at 13:11
  • Tom, we discovered the problem lay in my include code, the function I was using to determine if this was a 'teacher' archive was incorrect. But I am also going to set up my query like you outlined, so thanks. – semidivine May 10 '17 at 19:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.