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.