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

recent and related posts

What do we have to do?

  1. Create 2 instances of WP_Query class ($recent_query and $tags_query)
  2. By the help of these instances we have to create loops for recent and related posts
  3. IDs of the recent posts must be stored in an array for later use
  4. Implement displaying of the related posts based on tags
  5. 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>