How to avoid Duplicate posts in WordPress loop (multiple loops)?

How to avoid Duplicate posts in WordPress loop (multiple loops)?

Have you experienced duplicate posts appearing on your WordPress blog? By duplicate posts, I mean – posts repeating again-and-again in the post index. Basically, duplicate posts in WordPress appear due to the use of multiple loops in the WordPress themes.

A WordPress loop is responsible to display each of your posts, whether it’s the index of posts on your WordPress home page, category page, tag page, or it’s a single post. Read more about the loop at WordPress Codex, and that’s the same place where you’ll get the solution to avoid Duplicate posts in WordPress loop. I just have implemented that solution on this blog and am sharing my experience right here, hope it helps you to explore the problem and the solution a bit more.

I was using multiple loops in the main index template (index.php) of the blog to display posts from different categories. Below given is an overview of code I was using in my template:

<?php if(have_posts()) :
  // Loop#1
  $rp_query = new WP_Query('posts_per_page=4');
  while ($rp_query->have_posts()) :
    $rp_query->the_post(); ?>
    <h1><a href="<?php the_permalink(); ?> title="<?php the_title(); ?>"><?php the_title(); ?></a></h1>
    <?php the_excerpt();
  endwhile;
  // Loop#2 for category ID 23
  $sm_query = new WP_Query(array(
    'cat'  =>  23,
    'posts_per_page'  =>  3
  ));
  while ($sm_query->have_posts()) :
    $sm_query->the_post(); ?>
    <h1><a href="<?php the_permalink(); ?> title="<?php the_title(); ?>"><?php the_title(); ?></a></h1>
    <?php the_excerpt();
... ... ...
  endwhile;
endif; ?>

The first loop I’m using in the template displays 4 recent posts regardless of the category and the second loop pops posts from the category with ID 3 (that I specified in the query). The problem with the above code is: if I publish a post in category with ID 3, it will be shown two times, in the recent posts loop (Loop#1) and the loop for category ID 3 (Loop#2).

So, how to get rid of such a repetition of posts with multiple loops in WordPress? See the highlighted code in the below snippet which is an updated version of the above one:

<?php if(have_posts()) :
  // Loop#1
  $rp_query = new WP_Query('posts_per_page=4');
  while ($rp_query->have_posts()) :
    $rp_query->the_post(); ?>
    $dnd[] = $post->ID;
    <h1><a href="<?php the_permalink(); ?> title="<?php the_title(); ?>"><?php the_title(); ?></a></h1>
    <?php the_excerpt();
  endwhile;
  // Loop#2 for category ID 23
  $sm_query = new WP_Query(array(
      'cat'  =>  23,
      'post__not_in'  =>  $dnd,
      'posts_per_page  =>  3
  ));
  while ($sm_query->have_posts()) :
    $sm_query->the_post(); ?>
    <h1><a href="<?php the_permalink(); ?> title="<?php the_title(); ?>"><?php the_title(); ?></a></h1>
    <?php the_excerpt();
  endwhile;
... ... ...
endif; ?>

What we’ve done exactly: Collected the main loop’s post IDs in and array $dnd and told our next loop not to display the posts with any of the IDs stored in $dnd by making use of post__not_in handle in WP_Query.

Similarly, we can also tell our other loops to not to output the posts with the IDs stored in $dnd. Hope you find this useful.