Site icon Hip-Hop Website Design and Development

How to properly reset a nested WP_Query query

I’m missing something here. What’s the proper way to reset a query so that it doesn’t interfere with any other queries it may be nested in?

This is the kind of result I’m going for:

Main page

This is the main page content. Now let’s display some custom nested queries.

Outer page 1

 Inner post 1
 Inner post 2

Outer page 1 content continued…

Outer page 2

 Inner post 1
 Inner post 2

Outer Page 2 content continued…

…etc.

But I can’t get the Outer Page X content continued part working—it always reverts to either the inner query or the main page query.

Here’s my page template. It’s commented with the behavior I get with each of the reset functions (wp_reset_postdata(), wp_reset_query(), $query->reset_query(), and $query->reset_postdata()).

// BEGIN PAGE TEMPLATE 

while ( have_posts() ) : the_post();

    the_title(); // "Main page"

    /* --------- OUTER QUERY --------- */
    $outer_query = new WP_Query( [ 'post_type' => 'page' ] );

    if ($outer_query->have_posts()) : 
        while ($outer_query->have_posts()) : $outer_query->the_post();
            the_title(); // "Outer page 1", "Outer page 2", etc.

                /* --------- INNER QUERY --------- */
                $inner_query = new WP_Query( [ 'post_type' => 'post', 'posts_per_page' => 2 ] ); 

                if ($inner_query->have_posts()) :
                    while ($inner_query->have_posts()) : $inner_query->the_post();
                        the_title();
                    endwhile;
                endif;

            /**
             * Now I'm done with the inner query.
             * How do I get back to the outer query?
             * 
             * Desired value of the_title(): 
             *   "Outer page 1" on first iteration, "Outer page 2" on second, etc.
             */

            // wp_reset_postdata();            // Nope! Results in "Main page"
            // wp_reset_query();               // Nope! Results in "Main page" 
            // $inner_query->reset_postdata(); // Nope! Results in "Inner post 1"
            // $inner_query->reset_query();    // Nope! Results in "Inner post 2"
            // If no reset is used:            // Nope! Results in "Inner post 2"
            the_title();

        endwhile;
    endif;
    wp_reset_postdata();

    // Now back to the main page
    the_title(); // Works

endwhile;

// END OF PAGE TEMPLATE

What’s the proper way to do this? I’m looking for a generalizable answer that doesn’t rely on knowing how many levels deep the query is, or the context in which it’s being used. i.e., something that could be extracted into a shortcode.