In author.php I have two loops: the default *main loop* that gets all posts from that author, and another custom *WP_Query* called `$secondloop`. Both queries have `posts_per_page` set to **3**. Now I'd like to **paginate both query results**.

For this I've added an argument to `$secondloop = new WP_Query($args)`:

    "paged" => (get_query_var('paged')) ? get_query_var('paged') : 1;
(read: set this query's page to the same page as the *main query's*).

# THE PROBLEM: #
 
 - If the *main loop* gives me 5 posts and my `$secondloop` gives me 2, then calling **page 2** works no problemo. It shows me the remaining 2 posts from the *main loop* and none from my `$secondloop` (since it doesn't go inside `while ($secondloop->have_posts())`).
 
 - **BUT** if the *main loop* has 2 posts and `$secondloop` has 5, then calling **page 2** results in **404** :(
I obviously want `$secondloop`'s remaining 2 posts instead.

Changing anything inside the author.php template doesn't help, because it seems that no PHP code in there is executed any more, once WordPress detects that `max_num_pages` from the *main loop* is exceeded.

**How can I "override" that behaviour?**


---

# THE CODE: #

**author.php** (just the useful bit)

    <?php if (have_posts()) { ?>
        <div class="row archive-grid">
            <?php while (have_posts()) : the_post();
                include(locate_template('parts/loop-archive-grid.php'));
                endwhile; ?>
        </div>
    <?php }

    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $secondloop = new WP_Query(array(
        "post_type"      => "musikalbum",
        "posts_per_page" => 3,
        "author_name"    => get_query_var('author_name'),
        "paged"          => $paged
    ));

    if ($secondloop->have_posts()) { ?>
        <div class="row archive-grid">
            <?php while ($secondloop->have_posts()) : $secondloop->the_post();
                get_template_part( 'parts/loop', 'album-grid' );
            endwhile; ?>
        </div>
        <?php author_page_navi( $loop );
    } else {
        joints_page_navi();
    } ?>

Setting the `posts_per_page` for my *main query* in my **functions.php**

    function my_post_queries( $query ) {
      if (!is_admin() && $query->is_main_query()){
        if (is_author()){
          $query->set('posts_per_page', 3);
        } else {
          $query->set('posts_per_page', 9);
        }
      }
    }
    add_action( 'pre_get_posts', 'my_post_queries' );

----------

# EDIT: ATTEMPT 1 #

Milo pointed me to an answer that suggested to add this to my **functions.php**:

    function my_404_override() {
      global $wp_query;
      
      if (is_author()) {
        status_header( 200 );
        $wp_query->is_404 = false;
      }
    }
    add_filter('template_redirect', 'my_404_override');

But it still shows me a 404 error. If I remove the if clause, then it leads me to the index.php which is not reeeally what I intended. So I need that if clause...but WordPress doesn't seem to know it yet!

Pasting the code directly to the template didn't work either, even if it's just these three lines before `get_header();`:

    global $wp_query;
    status_header( 200 );
    $wp_query->is_404 = false;


----------

# EDIT: ATTEMPT 2 #

I ditched `template_redirect` for hooking into `pre_get_posts`:

    function my_post_queries( $query ) {
      if (!is_admin() && $query->is_main_query()){
        if (is_author()){
          $query->set('posts_per_page', 3);
          // NEW CODE:
          $paged = (get_query_var('paged')) ? intval(get_query_var('paged')) : 1;
          global $original_page_request; // saves the original value of $paged because I'm about to alter it!
          if ($paged > $query->max_num_pages) {
            $query->set('paged', $query->max_num_pages);
            $original_page_request = $paged;
        } else {
          $query->set('posts_per_page', 9);
        }
     }
    }
    add_action( 'pre_get_posts', 'my_post_queries' );

The idea was to manually set the main query page when it exceeds max_num_pages and store the "actual page" in `global $original_page_request` for everything that needs it.

I then edited **author.php**:

    global $original_page_request;
    // Check if max_num_pages is exceeded (= if $original_page_request is set!)
    // Also set the $paged variable for my $secondloop to the unaltered paged query var.
    if (empty($original_page_request)) {
        $is_within_max = true;
        $paged = get_query_var('paged') ? intval(get_query_var('paged')) : 1;
    } else {
        $is_within_max = false;
        $paged = $original_page_request;
    }
    
    // Main loop, hide it if max_num_pages exceeded!
    if ($is_within_max && have_posts()) { ?>
        <div class="row archive-grid">
            <?php while (have_posts()) : the_post();
                include(locate_template('parts/loop-archive-grid.php'));
            endwhile; ?>
        </div>
    <?php }

Problem is, it doesn't work. I was so happy not to see a 404 any more, but now it automatically sets the *main query* page to 0.

0?!

When hooking into `pre_get_posts`, this is exactly what `$query->max_num_pages` gives me. That's because by that time, it's **still in the process of gathering query variables and did not execute its query YET.** So there are no posts to show because no posts retreived, and thus no max_num_pages.

I then copied the new code from `my_post_queries( $query )` to another function which hooks into `wp`. There, I have access to max_num_pages and also the template I'm in. Still nothing. Because as soon as I exceed the number of posts, said code doesn't get executed. I could however set `$wp_query->is_404 = false` but that returns me to the index, yet again.