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 insidewhile ($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 reset paged
for the main query when it exceeds max_num_pages
and store the "actual page" in global $original_page_request
for my $secondloop
to set its paged
parameter to. Unfortunately though, 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. Why 0?!
Because in pre_get_posts
, code is executed before WordPress got its posts. There's access to $query
but that's just for setting query variables, there are no posts retreived, and thus no max_num_pages
to calculate from.
So that means I have no idea when I'm about to exceed max_num_pages.
I then copied the new code from my_post_queries( $query )
to another function which hooks into wp
. There, max_num_pages
is a valid number and is_author() is correct too. As soon as I exceed the number of posts, still no luck. 404. I could set $wp_query->is_404 = false
but that returns me to the index yet again.