Avoiding repeating posts with multiple loops

I recently completed a project for a popular online magazine. Because of the nature of magazines, the home page was full of custom loops, pulling in specific pieces of content from all over the site. However, it was very possible for content to show up in more than one loop. For example, at the top of the page was the most recent “Feature” and lower down in the page were several loops, pulling in content for posts in certain categories. Because the feature was categorised, just as the rest of the content was, we didn’t want it appearing in that loop, as it had already appeared elsewhere in the page.

The trick to getting around this is creating an array and adding every post that is displayed to that array and then using the post__not_in parameter in WP_Query to ignore any post in that array in future loops (i.e. posts that have already been displayed on the page).

See it in action in the Gist below:

There are two separate loops in this template (lines 1-20 & lines 22-45), though in the original template, there were about 10 or 12 loops, just extending this same practice.

In line 3, you note that we create an empty array called $do_not_duplicate. Then we have our custom WP_Query (lines 4-7), followed by its loop (lines 8-19). The very last thing we do inside the loop (on line 18) is add the post ID to the $do_not_duplicate array.

Now, WP_Query #2 is slightly different because we have added one more argument (line 32), which tells WordPress to ignore any post included in the $do_not_duplicate array, using the post__not_in parameter. This way, this loop cannot display any post which has appeared in a previous loop.

You can then replicate this behaviour for as many loops as you need, allowing you to have a large number of loops, pulling in content from all over your site without ever duplicating a post in any particular view.

4 thoughts on “Avoiding repeating posts with multiple loops”

  1. Maria says:

    Hey Dave, just curious – I don’t see that you’re doing it here, so maybe the answer is no – but do you need to reset the query after each loop? (so, using wp_reset_postdata();)

    1. Once your loop is complete and you’re finished with it, it’s probably wise to wp_reset_postdata in case you have any code that is relying on using the $post data for the main loop.

  2. Gerald says:

    Thanks for this excellent solution. I always messed with i++ for different styling but that #do_not_duplicate variable solves that way better.

  3. ravi D verma says:

    Hey Dave, my first loop(while) is in template page. and second one is in wordpress page for getting posts. i am facing the problem of extra content blocks. the all posts blocks are created. after my container. please help me . thank you.

Leave a Reply