0

I have a homepage and an archive page where I call a template part to have a hero section for the most recent posts, and then loop through the remaining posts as usual.

Essentially I don't want to show duplicate posts in the two different sections.

For example

//section 1
get_template_part('most-recent');

//section 2 - loop here
while ( have_posts() ) :

    the_post();
                    
    generate_do_template_part( 'index' );

endwhile;

In the template part, I just loop through the first 5 posts like so:

$i = 0;
while ( $i < 5 && have_posts() ) :

    the_post();
                    
    generate_do_template_part( 'index' );
    $i++;

endwhile;

The problem is this messes up the regular loop below - it doesn't show all posts anymore and the pagination is kind of broken.

I'm happy to create a new WP_Query in the template part, but I'd need to keep the default loop for the section below for compatibility with other features.

How could I achieve this?

EDIT: the comment below is right, there are no multiple queries, just looping through the main query multiple times to have a separate hero section with the first 5 posts.

3
  • 1
    is that your actual code? You mention multiple queries but there are none in your question, and the use of have_posts heavily implies that this is all for the main query, or that it uses the problematic query_posts function, or that there aren't multiple queries just multiple main loops for the same query. Can you edit your question to include information about how your queries work including the code? Try to avoid making things generic/abstract and use real code to avoid ambiguity and confusion
    – Tom J Nowell
    Dec 22, 2023 at 19:39
  • You're right. It's really similar to my actual code. The logic is the same the HTML differs. It's for the main query, using multiple loops to have a separate hero section with the first 5 posts. Not using query_posts.
    – lastnoob
    Dec 22, 2023 at 19:42
  • hmm that helps but doesn't make everything clear yet, when you say the template part can you edit your question to directly and explicitly state which template part so it isn't implied? Also what is generate_do_template_part? What you've shared indicates it's the same query but the first 5 posts are in another loop but if that were the case duplicates would already be impossible and you'd just have a hero section on every page, which is not what you're saying. The pagination code is also missing, and it's not clear what you mean by messing up
    – Tom J Nowell
    Dec 28, 2023 at 12:55

1 Answer 1

0

I think I've understood your question, and I hope this can help.

To display a hero section with the most recent posts without interfering with the main loop and pagination, you can use a combination of WP_Query for the hero section and pre_get_posts() to modify the main query. Here's the code to achieve this:

// Section 1 - Hero Section
$hero_args = array(
    'posts_per_page' => 5,  // Number of posts to display in the hero section
    // Add any other query parameters you need for the hero section
);

$hero_query = new WP_Query( $hero_args );

// Create an array to store the post IDs from the hero section
$hero_post_ids = array();

if ( $hero_query->have_posts() ) :
    while ( $hero_query->have_posts() ) :
        $hero_query->the_post();
        // Display content for the hero section here
        $hero_post_ids[] = get_the_ID(); // Store the post ID
    endwhile;
    wp_reset_postdata();  // Reset the hero section query
endif;

// Function to modify the main query
function modify_main_query( $query ) {
    if ( is_home() || is_archive() && $query->is_main_query() ) {
        // Exclude posts from the hero section
        $query->set( 'post__not_in', $hero_post_ids );
    }
}
add_action( 'pre_get_posts', 'modify_main_query' );

// Section 2 - Regular Loop
while ( have_posts() ) :
    the_post();
    // Display content for the regular loop here
endwhile;

// Pagination for the regular loop
the_posts_pagination();

This code creates a separate WP_Query for the hero section, displays its content, and then modifies the main query using pre_get_posts to exclude the post IDs from the hero section, ensuring that they won't appear in the main loop. This approach maintains proper pagination and prevents duplicate posts between the hero section and the main loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.