display posts with same taxonomy term

I’m trying to display 5 related posts in the loop, those related posts being posts that share the same taxonomy value. e.g. I have a custom taxonomy set up called venues thus each post has a venue taxonomy value assigned to it, so in each post I want to display 5 others posts that share the same taxonomy value (i.e. are at the same venue).
The code I have so far doesn’t work quite right:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php
$custom_terms = get_terms('venues');

foreach($custom_terms as $custom_term) {
    wp_reset_query();
    $args = array('post_type' => 'listings',
    'posts_per_page' => 5,
        'tax_query' => array(
            array(
                'taxonomy' => 'venues',
                'field' => 'slug',
                'terms' => $custom_term->slug,
            ),
        ),
     );

     $loop = new WP_Query($args);
     if($loop->have_posts()) {

        while($loop->have_posts()) : $loop->the_post(); ?>
        <div class="listing-title"><?php the_title(); ?></div>     
        <?php endwhile;
     }
}
?>
<?php wp_reset_query(); ?>
<?php endwhile; endif; ?>

It is successfully showing 5 posts, but they are just five posts from the same post type and not 5 posts that share the same taxonomy value in the loop. Any suggestions would be greatly appreciated!

Related posts

Leave a Reply

2 comments

  1. Totally untested and I’m not 100% sure I understand your question, but this should (in theory) get 5 posts that share any of the same venues as the current post. I would probably suggest adding some Transients to this so that you aren’t constantly running queries.

    If it doesn’t work, I suspect the syntax of my tax query is a little off. It always gets me because it is an array of arrays.

    //get the post's venues
    $custom_terms = get_terms('venues');
    
    if( $custom_terms ){
    
        // going to hold our tax_query params
        $tax_query = array();
    
        // add the relation parameter (not sure if it causes trouble if only 1 term so what the heck)
        if( count( $custom_terms > 1 ) )
            $tax_query['relation'] = 'OR' ;
    
        // loop through venues and build a tax query
        foreach( $custom_terms as $custom_term ) {
    
            $tax_query[] = array(
                'taxonomy' => 'venues',
                'field' => 'slug',
                'terms' => $custom_term->slug,
            );
    
        }
    
        // put all the WP_Query args together
        $args = array( 'post_type' => 'listings',
                        'posts_per_page' => 5,
                        'tax_query' => $tax_query );
    
        // finally run the query
        $loop = new WP_Query($args);
    
        if( $loop->have_posts() ) {
    
            while( $loop->have_posts() ) : $loop->the_post(); ?>
    
            <div class="listing-title"><?php the_title(); ?></div>     
            <?php endwhile;
        }
    
        wp_reset_query();
    
    }?>
    
  2. Thank you for good solution, but that one will get you posts with any term in same taxonomy. But if you want only the ones which have same terms with current post you need to modify code like this. This one is tested and should work.

     <?php
            //get the post's venues
        $custom_terms = wp_get_post_terms($post->ID, 'venues');
    
        if( $custom_terms ){
    
            // going to hold our tax_query params
            $tax_query = array();
    
            // add the relation parameter (not sure if it causes trouble if only 1 term so what the heck)
            if( count( $custom_terms > 1 ) )
                $tax_query['relation'] = 'OR' ;
    
            // loop through venus and build a tax query
            foreach( $custom_terms as $custom_term ) {
    
                $tax_query[] = array(
                    'taxonomy' => 'venues',
                    'field' => 'slug',
                    'terms' => $custom_term->slug,
                );
    
            }
    
            // put all the WP_Query args together
            $args = array( 'post_type' => 'listings',
                            'posts_per_page' => 5,
                            'tax_query' => $tax_query );
    
            // finally run the query
            $loop = new WP_Query($args);
    
            if( $loop->have_posts() ) {
    
                while( $loop->have_posts() ) : $loop->the_post(); ?>
    
                <div class="listing-title"><?php the_title(); ?></div>     
                <?php 
    
                endwhile;
    
            }
    
            wp_reset_query();
    
        }?>