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?
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. My guess is that
- either this code gets executed before WordPress knows what template it's dealing with (trying to execute get_current_template(true) in there throws an "Undefined function" error)
- OR because
$wp_query->is_404
is true by the time this code is run, it doesn't attempt to load the author.php template.
Pasting the code directly to the template didn't work either, even if it's just these three lines pasted before get_header();
:
global $wp_query;
status_header( 200 );
$wp_query->is_404 = false;
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' );
And here are the pagination functions used from my JointsWP4 starter theme:
<?php // This function was standard from my JointsWP4 starter theme...
function joints_page_navi($before = '', $after = '') {
global $wpdb, $wp_query;
$request = $wp_query->request;
$posts_per_page = intval(get_query_var('posts_per_page'));
$paged = intval(get_query_var('paged'));
$numposts = $wp_query->found_posts;
$max_page = $wp_query->max_num_pages;
//...except for this line, since author_page_navi uses the same logic:
page_navi_logic( $posts_per_page, $paged, $numposts, $max_page );
}
// A "hacked" version of joints_page_navi() for my $secondloop to work (or not)
function author_page_navi( $loop ) {
global $wpdb, $wp_query;
$request = $wp_query->request;
$posts_per_page = max(intval($wp_query->posts_per_page), intval($loop->posts_per_page));
$paged = intval(get_query_var("paged"));
$numposts = max($wp_query->found_posts, $loop->found_posts);
$max_page = max($wp_query->max_num_pages, $loop->max_num_pages);
page_navi_logic( $posts_per_page, $paged, $numposts, $max_page );
}
function page_navi_logic( $posts_per_page, $paged, $numposts, $max_page ) {
if ( $numposts <= $posts_per_page ) { return; }
if(empty($paged) || $paged == 0) {
$paged = 1;
}
$pages_to_show = 3;
$pages_to_show_minus_1 = $pages_to_show-1;
$half_page_start = floor($pages_to_show_minus_1/2);
$half_page_end = ceil($pages_to_show_minus_1/2);
$start_page = $paged - $half_page_start;
if($start_page <= 0) {
$start_page = 1;
}
$end_page = $paged + $half_page_end;
if(($end_page - $start_page) != $pages_to_show_minus_1) {
$end_page = $start_page + $pages_to_show_minus_1;
}
if($end_page > $max_page) {
$start_page = $max_page - $pages_to_show_minus_1;
$end_page = $max_page;
}
if($start_page <= 0) {
$start_page = 1;
}
echo $before.'<nav class="push-down"><ul class="pagination">'."";
if ($start_page >= 2 && $pages_to_show < $max_page) {
$first_page_text = __( 'Erste...', 'jointswp' );
echo '<li><a href="'.get_pagenum_link().'" title="'.$first_page_text.'">'.$first_page_text.'</a></li>';
}
echo '<li>';
previous_posts_link( __('Back', 'jointswp') );
echo '</li>';
for($i = $start_page; $i <= $end_page; $i++) {
if($i == $paged) {
echo '<li class="current"> '.$i.' </li>';
} else {
echo '<li><a href="'.get_pagenum_link($i).'">'.$i.'</a></li>';
}
}
echo '<li>';
next_posts_link( __('Forward', 'jointswp'), $max_page );
echo '</li>';
if ($end_page < $max_page) {
$last_page_text = __( 'Last...', 'jointswp' );
echo '<li><a href="'.get_pagenum_link($max_page).'" title="'.$last_page_text.'">'.$last_page_text.'</a></li>';
}
echo '</ul></nav>'.$after."";
}