Archived topic
Multiple loops on homepage without duplicate posts
7 replies · Started by Arthur on December 8, 2020
I am trying to set up multiple loops on my homepage but would like to avoid displaying duplicates. I have the following code working but thinking it will be more efficient to combine these into one loop, to avoid using additional database resources for a high traffic site. Any help would be much appreciated.
`<?php
/**
* The main template file.
*
* This is the most generic template file in a WordPress theme
* and one of the two required files for a theme (the other being style.css).
* It is used to display a page when nothing more specific matches a query.
* E.g., it puts together the home page when no home.php file exists.
* Learn more: http://codex.wordpress.org/Template_Hierarchy
*
* @package GeneratePress
*/
/* CUSTOM CODE FOR HOMEPAGE */
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
get_header(); ?>
<section class="main-col">
<?php
/* CUSTOM LOOP FOR HERO POSTS - TIER 1*/
$args = array(
'meta_key' => 'meta-box-dropdown',
'posts_per_page' => 1,
'meta_value' => 'Tier 1',
);
$tier1_query = new WP_Query($args);
if ( generate_has_default_loop() ) {
if ( have_posts() ) :
while ( $tier1_query->have_posts() ) :
$tier1_query->the_post();
get_template_part( 'content','tier1');
//print get_post_meta( $post->ID, 'meta-box-dropdown', true );
endwhile;
/**
* generate_after_loop hook.
*
* @since 2.3
*/
do_action( 'generate_after_loop', 'index' );
else :
generate_do_template_part( 'none' );
endif;
}
wp_reset_query();
?>
</section>
<aside class="sidebar-col">
<?php
/* CUSTOM LOOP FOR HERO POSTS - TIER 2*/
$args = array(
'meta_key' => 'meta-box-dropdown',
'posts_per_page' => 4,
'meta_value' => 'Tier 2',
);
$tier2_query = new WP_Query($args);
if ( generate_has_default_loop() ) {
if ( have_posts() ) :
while ( $tier2_query->have_posts() ) :
$tier2_query->the_post();
get_template_part( 'content','tier2');
endwhile;
/**
* generate_after_loop hook.
*
* @since 2.3
*/
do_action( 'generate_after_loop', 'index' );
else :
generate_do_template_part( 'none' );
endif;
}
wp_reset_query();
?>
</aside>
<main id="main" <?php generate_do_element_classes( 'main' ); ?>>
<h2>Latest Stories</h2>
<?php
/**
* generate_before_main_content hook.
*
* @since 0.1
*/
do_action( 'generate_before_main_content' );
wp_reset_query();
if ( generate_has_default_loop() ) {
if ( have_posts() ) :
while ( have_posts() ) :
the_post();
generate_do_template_part( 'index' );
endwhile;
/**
* generate_after_loop hook.
*
* @since 2.3
*/
do_action( 'generate_after_loop', 'index' );
else :
generate_do_template_part( 'none' );
endif;
}
/**
* generate_after_main_content hook.
*
* @since 0.1
*/
do_action( 'generate_after_main_content' );
?>
</main>
<?php
/**
* generate_after_primary_content_area hook.
*
* @since 2.0
*/
do_action( 'generate_after_primary_content_area' );
generate_construct_sidebars();
get_footer();
'
Hi there,
This is likely somewhat out of scope for the forum here, but this solution I provided in our WPSP forum may help: https://wpshowposts.com/support/topic/stop-showing-duplicate-posts-on-the-same-page-post-using-a-different-shortcode/#post-15716
Basically, add this to the beginning of each loop:
global $added_ids;
$added_ids[] = get_the_ID();
Then add this to the args for each query:
global $added_ids;
// Exclude posts that have already been added.
$args['post__not_in'] = $added_ids;
Hope it helps :)
That worked great. Thank you Tom.
You're welcome :)
On second thought, looks like the first post is being added to $added_ids twice. Any ideas why this might be happening?
Screenshot
If that post is being queried twice, it will be added to the array twice.
To prevent that, you can do something like this:
if ( ! in_array( get_the_ID(), $added_ids ) ) {
$added_ids[] = get_the_ID();
}
Got it thank you. I added the code and seems to have helped eliminate the duplicate post. Now for some odd reason, the last post ID is not being added to the $added_ids array. I understand this probably out of scope of general theme support but if you have any clues that would be much appreciated Tom.
<?php
/* CUSTOM LOOP FOR HERO POSTS - TIER 2*/
wp_reset_postdata();
global $added_ids;
$args2 = array(
'meta_key' => 'meta-box-dropdown',
'meta_value' => 'Tier 2',
'posts_per_page' => 4,
'post__not_in' => $added_ids,
);
$tier2_query = new WP_Query($args2);
if ( generate_has_default_loop() ) {
if ( have_posts() ) :
while ( $tier2_query->have_posts() ) :
global $added_ids;
if ( ! in_array( get_the_ID(), $added_ids ) ) {
$added_ids[] = get_the_ID();
}
$tier2_query->the_post();
print 'POST ID: '.get_the_ID();
get_template_part( 'content','tier2');
endwhile;
wp_reset_postdata();
/**
* generate_after_loop hook.
*
* @since 2.3
*/
do_action( 'generate_after_loop', 'index' );
else :
generate_do_template_part( 'none' );
endif;
}
print ('<br><br>ADDED IDS: <br>');
print_r($added_ids);
?>
Hmm, it could be the in_array() check I suppose, it would take some playing with to figure out. Technically, every ID that runs inside a loop should be added to that global variable.