Get Related Posts For Custom Post Type by Custom Taxonomy

This code will get the related posts of the current custom-post-type single post being viewed. This will get posts only of the same custom post type and the same custom taxonomy term of the current single post. Use this code on single.php, or on single-custom_post_type.php. Use it to show a custom loop of related items on the sidebar or footer of the current single custom post.

Note: this code is only necessary for getting related posts by custom taxonomies. For a custom post type that supports regular categories, then do this instead: Get Related Posts For Custom Post Type By Category. Or, for regular posts, see Related Posts By Category.


<!-- begin custom related loop, isa -->

<?php 

// get the custom post type's taxonomy terms

$custom_taxterms = wp_get_object_terms( $post->ID, 'your_taxonomy', array('fields' => 'ids') );
// arguments
$args = array(
'post_type' => 'your_custom_post_type',
'post_status' => 'publish',
'posts_per_page' => 3, // you may edit this number
'orderby' => 'rand',
'tax_query' => array(
    array(
        'taxonomy' => 'your_taxonomy',
        'field' => 'id',
        'terms' => $custom_taxterms
    )
),
'post__not_in' => array ($post->ID),
);
$related_items = new WP_Query( $args );
// loop over query
if ($related_items->have_posts()) :
echo '<ul>';
while ( $related_items->have_posts() ) : $related_items->the_post();
?>
    <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php
endwhile;
echo '</ul>';
endif;
// Reset Post Data
wp_reset_postdata();
?>


<!-- end custom related loop, isa -->

For this loop to work for you, you must make the following changes to the code:

On line 7: change ‘your_taxonomy’ to the name of your custom taxonomy. Leave in the single quotes.

On line 10: change ‘your_custom_post_type’ to the name of your custom post type. Leave in the single quotes.

On line 12: optionally, change the number 3 to whatever number you need.

On line 16: change ‘your_taxonomy’ to the name of your custom taxonomy. Leave in the single quotes.

Optional: Change the display by changing the html on lines 26, 29, and 32. Add a thumbnail, or whatever.

See more: , ,

We've 40 Responses

  1. June 26th, 2012 at 11:50 am

    Hi, thanks on your reply… I used your code here and it worked but I still have the same issue than with my code. the code show all posts from custom taxonomy “material”. And I need all the posts from the child taxonomy the single-custom is in. for example all the posts on “leather” or “plastic”

    *** Original question ***
    How would you change the code to use it on single-custom.php
    with custom post type “bags”
    and custom taxonomy:
    1. material
    1.1 Leather
    1.2 Plastic
    1.3 Paper

    I need to show below the single-post all the other custom-post from the product taxonomy :S

    Ej: Single-custom.php show bag with leather taxonomy.
    I need to show below all the other custom-post with the same taxonomy

    What i have so far:

    
    'globos', 'posts_per_page' => 100 ) ); ?>
    have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post(); ?>
    <a class="thumb-globo" href="”>
    
    funky
    • June 26th, 2012 at 1:15 pm

      Oh, I misunderstood. I thought leather, plastic, and paper were the taxonomy terms of the ‘material’ taxonomy. I didn’t realize they were child taxonomies. I tested the code, and it works for my case, in which “leather, plastic, and paper” are terms of the taxonomy, not children. This code will then show only all the ‘leather’ or only ‘plastic’, etc.

      But in your case, I can’t see why you would make them “child taxonomies.” Is there a reason why you made them child taxonomies, instead of just terms of the ‘material’ taxonomy?

      Isabel
      • June 26th, 2012 at 1:34 pm

        I’M SORRY YOU ARE RIGHT THEY ARE TERMS

        BUT STILL HAVENT FOUND A WAY TO SET THE RELATED POSTS ONLY FROM THAT TERM.
        THIS IS MY SINGLE-CUSTOM.PHP

        <link rel="stylesheet" href="/css/pagePost.css” type=”text/css” />
        
        <div id=”post-”>
        
        
        ID, ‘materials’ );
        
        foreach( $terms as $term )
        $term_names[] = $term->name;
        
        echo ” . $term_names[0] . ‘ ‘;?>
        
        ID, ‘sizes’);
        $project_cats = array_values($project_cats);
        for($cat_count=0; $cat_countname;
        if ($cat_count
        ‘Pages: ‘, ‘next_or_number’ => ‘number’)); ?>
        
        
        ID, ‘materials’, array(‘fields’ => ‘ids’) );
        $args = array(
        ‘post_type’ => ‘bags’,
        ‘post_status’ => ‘publish’,
        ‘posts_per_page’ => 100,
        ‘orderby’ => ‘rand’,
        ‘tax_query’ => array(
        array(
        ‘taxonomy’ => ‘materials’,
        ‘field’ => ‘id’,
        ‘terms’ => $custom_taxterms
        )
        ),
        ‘post__not_in’ => array ($post->ID),
        );
        $related_items = new WP_Query( $args );
        if ($related_items->have_posts()) :
        echo ”;
        while ( $related_items->have_posts() ) : $related_items->the_post();
        ?>
        <a href="” title=”">
        <?php
        endwhile;
        echo '’;
        endif;
        wp_reset_postdata();
        ?>
        

        the loop from your code print all post from the taxonomy Material. And I need to print if the single-custom post is showing a post from leather, all other post from leather…

        funky
  2. June 26th, 2012 at 1:45 pm

    I got it. i just had to put after: $custom_taxterms[0] to set the current one….

    'tax_query' =&gt; array(
        array(
            'taxonomy' =&gt; 'your_taxonomy',
            'field' =&gt; 'id',
            'terms' =&gt; $custom_taxterms[0]
        )
    ),
    

    thanks a lot for your help!

    funky
  3. December 4th, 2013 at 1:48 pm

    Now work for me

    foreach((get_the_terms($post-&gt;ID, 'preco')) as $term) {
            $termID = $term-&gt;term_id;
            $simular = array(
            'post_type' =&gt; 'imoveis',
            'post_status' =&gt; 'publish',
            'posts_per_page' =&gt; 3, // you may edit this number
            'orderby' =&gt; 'rand',
            'tax_query' =&gt; array(
                array(
                    'taxonomy' =&gt; 'preco',
                    'field' =&gt; 'id',
                    'terms' =&gt; $termID
                )
            ),
            'post__not_in' =&gt; array ($post-&gt;ID),
            );
            }
    
    Anderson
  4. January 6th, 2014 at 11:24 am

    Hi!

    It’s so easy when you know how to do it, right? THANKS A BUNCH FOR SHARING! Couldn’t find valid hints for this anywhere. This msg didn’t post first time I tried, maybe the session timed out. Checked the rest of your site meanwhile and had to go back and THANK YOU! Awesome tips. Will use some.

    All the best from Stockholm,
    T

    Tdude
  5. January 7th, 2014 at 3:21 pm

    Thank you so much, this has been a huge help as I didn’t want to static-ly query an array of the existing terms in the taxonomy. Definitely makes it dynamic for the client, thanks again!

    Chris C
  6. January 29th, 2014 at 12:54 pm

    It works really well, thank you soooo much!
    Is it possible to relate the posts with 2 or more taxonomies? I’ve tried replace the “your_taxonomy” part with “array(‘taxonomy1′,’taxonomy1’)” but it didn’t work 🙁
    I’m not very familiar with php or wordpress, could you give me a hint?

    Thanks! 🙂

    Isabela Sampaio
  7. November 6th, 2014 at 5:32 am

    Hi! Thank you so much for the code! It worked as intended. However, it did not display anything when I tried putting it in functions.php.

    I put the function in single-mycustom.php like this:

    if ( function_exists('related_posts_cpt') ){
        related_posts_cpt();
    }
    

    And put your code in functions.php:

    function related_posts_cpt(){
    // your code here
    }
    

    Thanks again! 🙂

    Carlo
    • November 6th, 2014 at 5:39 am

      Hello again. I was able to make it work by putting global $post; above your codes. Just posting it here in case some newbie like me encounter the same problem. 🙂

      function related_posts_cpt(){
          global $post;
          // your code here
      }
      
      Carlo
      • November 6th, 2014 at 6:14 pm

        Thank you. Yes, putting in a function like you did is a much cleaner solution. And, yes, you got it right, you need global $post in the function. 🙂

        Isabel
    • December 4th, 2014 at 6:03 pm

      Do you mean to relate 2 taxonomy terms, or 2 different taxonomies?

      If you do want to relate 2 taxonomies, insert the following line under line 7 of the code above. Replace ‘second_taxonomy’ with the slug of your second taxonomy:

      $custom_taxterms_two = wp_get_object_terms( $post->ID, 'second_taxonomy', array('fields' => 'ids') );

      Then, replace the tax query (lines 14 through 20) with this:

      'tax_query' => array(
      		'relation' => 'OR',
      		array(
      			'taxonomy' => 'your_taxonomy',
      			'field'    => 'id',
      			'terms'    => $custom_taxterms
      		),
      		array(
      			'taxonomy' => 'second_taxonomy',
      			'field'    => 'id',
      			'terms'    => $custom_taxterms_two
      		),
      	),
      

      Replace ‘your_taxonomy’ and ‘second_taxonomy’ in this snippet. This block replaces lines 14 through 20. This will show related posts that have matching terms in either of your two specified taxonomies. Hope that helps.

      Isabel
      • July 21st, 2019 at 8:07 pm

        How to make not by 1taxonomy AND 2taxonomy related posts. But how to make 1taxnomy OR 2taxonomy related posts? Not “AND”, but “OR”?

        Bruno
        • August 8th, 2019 at 5:11 pm

          To show posts from either one taxonomy or the other, make some empty lines at the beginning of line 23 (move the existing line 23 down to create empty lines). Then, insert this:

          foreach($custom_taxterms as $t) {
              $args['tax_query'][] = array(
                  'taxonomy' => 'your_taxonomy',
                  'field'    => 'id',
                  'terms'    => $t,
              );
          }
          

          In this code snippet, be sure to change your_taxonomy to the name of your custom taxonomy on line 3.

          AND THEN, change lines 15–19 to just this:

          'tax_query' => array('relation' => 'OR')

          That will change the relation to “OR” instead of “AND”.

          Isabel
  8. September 9th, 2015 at 11:35 pm

    Thanks much for this Isabel. I’m trying to get 3 posts from the custom post type “cars”, with the taxonomy term “color”, and the taxonomy tag “red”. If I’m not mistaken, your code would get any post with the term “color” attached to it, not just the red ones, correct? If so, how do I edit it to be more specific?

    Dean H
    • September 10th, 2015 at 12:45 pm

      Hi. No, actually, it will get only the posts with the same color of whichever post is viewed at the time. So, on a post tagged with “red”, it will get other posts tagged with “red.” On lines 7 and 16, change ‘your_taxonomy‘ to ‘color‘, though. It gets confusing, but it will work that way to show only posts with the same color of the current post. I hope that helps.

      Isabel
  9. March 13th, 2016 at 12:13 am

    I’ll add my thanks — saved me loads of time! Only question:
    I have a custom taxonomy that applies to BOTH “posts” and a custom post type (“podcast”). I want to use my custom taxonomy to display a mix of results from both post types. Would appreciate any tips!

    Cortney

Questions and Comments are Welcome

Your email address will not be published. All comments will be moderated.

Please wrap code in "code" bracket tags like this:

[code]

YOUR CODE HERE 

[/code]