A good technique to help minimize bounce rates in a website is to offer content related to the one that is currently being consumed by the user. We’re going to learn here how to achieve this in WordPress using custom taxonomies, but you can use post tags or categories with the same code.
Custom taxonomies
What we are going to do in this tutorial, is to display other posts related to the current post filtering them by its terms applied in a custom taxonomy from WordPress. These taxonomies allow us to group things under different terms. In this case, we will use a taxonomy named color, and the terms to group by will be colors: blue, red, green, orange, pink, etc.
Then, when the visitor is reading a post including terms from color taxonomy like orange or beige, we will query our posts to see if there are other entries containing the same terms and will display these posts or entries in a block with some title like “Related posts by color”.
Code to display related posts
Let’s check the full code first. One place that you could use this is in the single.php template of your WordPress theme. The single.php template is used by WordPress to display individual entries, thus making it perfect to show related content.
[php]
<div id="related-posts">
<h3>Related posts by color</h3>
<?php
global $post;
$terms = get_the_terms( $post->ID , ‘color’, ‘string’);
$do_not_duplicate[] = $post->ID;
if(!empty($terms)){
foreach ($terms as $term) {
query_posts( array(
‘color’ => $term->slug,
‘showposts’ => 4,
‘caller_get_posts’ => 1,
‘post__not_in’ => $do_not_duplicate ) );
if(have_posts()){
while ( have_posts() ) : the_post(); $do_not_duplicate[] = $post->ID; ?>
<div id="post-<?php the_ID(); ?>" class="related-post">
<?php the_title();?>
<div class="ilc-excerpt">
<?php the_excerpt(); ?>
</div>
</div>
<?php endwhile; wp_reset_query();
}
}
}
?>
</div>
[/php]
We will first instantiate the global variable $post, to access the current post data. Then we collect the terms in the entry with get_the_terms. We’re also going to initialize an array with the ID of the current post, so that we won’t repeat it again in the related posts (since it has the same terms it would appear in the new query).
The code now checks if there are any terms in the entry, checking if $terms is empty. If there are terms, we enter into a foreach loop iterating through each term. Now we’re ready to query the posts, comparing their terms in the color taxonomy to see if any of them match those of the current post. We will display only 4 related posts but feel free to change this number. Finally, we use the $do_not_duplicate defined earlier to indicate that we don’t want entries that array.
If the query was successful, we’ll have some entries to show and hence, we will enter The Loop. In this simple example we’re only showing the title and the excerpt but you can use any other function tag that work within The Loop. You can see a working sample of this code. It’s very similar, but it uses other calls to the_post_thumbnail and other post information such as the category.
Don’t think this code restricts you to use it only with custom taxonomies, you can also use it with post_tag or category, WordPress’ default taxonomies for tags and categories. Just change the taxonomy name from color to any of the two and it will work with the tags that you assign to your post or the categories defined for the post.
Nice, thanks! The only thing I would improve is that if you’re using multiple categories (for example two colors for a single item) at the same time, you might end up with duplicate items.
I simply pushed the post_id to the $do_not_duplicate array inside the loop, and that did the trick.
Hey Sacha Greif, I know you man, you’ve some cool artwork.
Excluding duplicates is what this line
$do_not_duplicate[] = $post->ID; ?>
within the loop does for each post.
Didn’t wanted to use push() for one single element each time, since calling a function is much more expensive than assign the value to the array’s next empty slot.
My bad, you’re right! I think I deleted that line by mistake when tweaking the code then re-wrote it myself differently…
And by the way, thanks for the praise 🙂
Thanks very much for this. It is fantastic. Quick question: you’ve got the h3 at the top as the header which is great for static placement but I’m wondering what I could do to move that within the query to get the taxonomy displayed, so that it would display “More from whatever taxonomy this is.”
Hi Christopher, you can try the following:
[php]
if(have_posts()){
echo ‘<h3>Related posts by’ . ucwords($term->name) . ‘</h3>’;
//loop begins
[/php]
I’ve added a ucwords to capitalize the first character of each word but you can remove it. Let me know how it goes.
Thanks! That worked perfectly.
Hey man, thanks! help me a lot!
Everything works perfectly! But the “showposts” just limits the number of posts FOR EACH Taxonomy Term…is there a way to limit also the WHOLE Number of Posts which will be listed???
@Richard:
I had the same problem, and I fixed it by changing:
foreach ($terms as $term) {
to:
foreach ($posts as $post) {
Works perfectly!
Thanks for a great tutorial! 🙂
Hi DirTek, a updated code to make use of new tax_query in WP 3.1, and to achieve the restriction of the whole number of posts would be:
[php]
global $post;
$terms = get_the_terms( $post->ID , ‘color’, ‘string’);
$do_not_duplicate[] = $post->ID;
$allterms = [];
if(!empty($terms)){
foreach ($terms as $term)
$allterms[] = $term->slug . ",";
query_posts( array(
‘tax_query’ => array(
array(
‘taxonomy’ => ‘color’,
‘field’ => ‘slug’,
‘terms’ => $allterms
)
),
‘showposts’ => 4,
‘caller_get_posts’ => 1,
‘post__not_in’ => $do_not_duplicate ) );
if(have_posts()){
//rest of the code continues…
[/php]
In this case the terms to be queried are first stored in an array and the passed as a subparameter of the new tax_query parameter introduced in WP3.1.
Hi !! Thank so much !!
I just have a question. If I need use it on all posts they don’t have the same taxonomy. Or if my post have several taxonomy depends. Do you know how to proceed to display all related posts ? Or just an idea ? Thank you
Bobdad, you’re going to have to use multiple taxonomy querying with tax_query parameter for query_posts, as it’s supported since WP 3.1. In the example above in reply to another commenter there’s a quick use of tax_query.
Check for more info in WP_Query taxonomy parameters section.
Thank you Elio. Finally I have used get_taxonomies() to have the taxonomy list and the function wp_get object_terms :
My code, if it’s could be useful : wp_get_object_terms( $post->ID , get_taxonomies() );
Hello, Elio,
regarding the “showposts” issue with displaying wanted number of posts per tag, not the wanted number of related posts in general, – the updated code you provided few comments earlier doesn’t seem to work at all: first, it gives a faal error when trying to do this:
$allterms = [];
And then it doesn’t seem to find any related posts at all. My guess is the problem is in the $allterms array. Can you help with this?
Weird. I keep getting
Parse error: syntax error, unexpected '[' in
at line 4’s do_not_duplicate and that stops it. I am using Elio’s updated version in the comment of June 21.[…] => true, 'rewrite' => true ) ); } ?> And the following code to single.php (original article found here). The last part of the script ensures the thumbnail is used to show the post (I created a custom […]
[…] the following code to single.php (original article found here). The last part of the script ensures the thumbnail is used to show the post (I created a custom […]
Thanks a lot for this post! Helped me out…