Display recent and related posts without duplicating each other
My client asked me to implement lists of recent and related posts below a single post without duplicating each other.

What do we have to do?
- Create 2 instances of WP_Query class ($recent_query and $tags_query)
- By the help of these instances we have to create loops for recent and related posts
- IDs of the recent posts must be stored in an array for later use
- Implement displaying of the related posts based on tags
- In the loop for tags we have to exclude IDs of recent posts from displaying
This tutorial has two parts:
- Recent posts
- Related posts
Recent posts
This is how full code for recent posts looks:
<?php
/**
* recent posts
*/
?>
<h2>recent 5 posts</h2>
<?php $recent_query = new WP_Query(); ?>
<?php $recent_query->query('showposts=5'); $ids = array(); ?>
<ul>
<?php while($recent_query->have_posts()) : $recent_query->the_post();
$ids[] = get_the_ID(); // we have to store IDs in the array for later use
?>
<li>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</li>
<?php endwhile; ?>
</ul>
Now let’s go step by step:
The first we have to create instance of the WP_Query() class. Its references retain a lot of info that we can use later. More info about this class you can find in the function reference.
<?php $recent_query = new WP_Query(); ?>
With the instance of WP_QUery we can query posts. We also have to create an array $ids that we’ll use later for storing IDs of the rcent posts we displayed.
<?php
$recent_query->query('showposts=5'); // we are going to display 5 posts
$ids = array(); // create array we will use for storing recent posts' IDs
?>
Using $recent_query object we can run a loop to display last 5 posts. We also have to get the ID of each post and store it in $id array. Note that the loop is inside ul tags i.e we want to repeat only list items with unique permalinks, not whole list.
<ul>
<?php while($recent_query->have_posts()) : $recent_query->the_post();
$ids[] = get_the_ID(); // we have to store IDs in the array for later use
?>
<li>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</li>
<?php endwhile; ?>
</ul>
Related posts
Here is a code of displaying of the related posts based on tags.
<?php
/**
* related posts
*/
$tags = wp_get_post_tags( array('showposts' => 5, 'post__not_in'=>$ids) );
$tag_ids = array();
foreach ($tags as $individual_tag)
$tag_ids[] = $individual_tag->term_id;
$args = array(
'tag__in'=>$tag_ids,
'post__not_in'=>$ids, // while using $recent_query we created $ids[] array with IDs of the recent posts
'showposts'=>5, // Number of related posts that will be shown.
'caller_get_posts'=>1);
$tags_query = new WP_Query($args);
if ($tags_query->have_posts()) {
?>
<div class="related-posts">
<h2>Related posts</h2>
<ul>
<?php while ($tags_query->have_posts()) { $tags_query->the_post(); ?>
<li>
<a href="<?php the_permalink() ?>"><?php the_title(); ?></a>
</li>
<?php } ?>
</ul>
</div>
<?php
}
?>
The first we have create an array of tags and exclude recent posts. This we do by adding an array $ids to the parameter ‘post__not_in’.
$tags = wp_get_post_tags( array('showposts' => 5, 'post__not_in'=>$ids) );
Store the tags’ ID’s in the array $tag_ids
$tag_ids = array();
foreach ($tags as $individual_tag)
$tag_ids[] = $individual_tag->term_id;
Prepare $args – arguments we want to set for $tags_query instance of the WP_Query class.
Note argument ‘post__not_in’ => $ids to which we assign array of the IDs of the recent posts. They won’t be displayed in the related posts.
$args = array(
'tag__in'=>$tag_ids,
'post__not_in'=>$ids, // while using $recent_query we created $ids[] array with IDs of the recent posts
'showposts'=>5, // Number of related posts that will be shown.
'caller_get_posts'=>1);
$tags_query = new WP_Query($args);
If there are posts that meet our conditions:
if ($tags_query->have_posts()) {
Start displaying related posts based on the their tags:
<div class="related-posts">
<h2>Related posts</h2>
<ul>
<?php while ($tags_query->have_posts()) { $tags_query->the_post(); ?>
<li>
<a href="<?php the_permalink() ?>"><?php the_title(); ?></a>
</li>
<?php } ?>
</ul>
</div>
