We use latest WP (5.2.2). We have a custom post type called Stories (slug: stories) with the following capabilities during setup.
Public: true
Publicly Queryable: true
Show UI: true
Has Archive: true
Exclude From Search: false
Hierarchical: false
Rewrite: true
Custom Rewrite Slug: stories/%category%
Show in Nav Menus: true
Show in REST API: true
With Front: true
Query Var: true
This works fine. For example, we create a new story called "Huckleberry Cafe Opens" and assign it to a category called "Food", and the URL works:
site.com/stories/food/huckleberry-cafe-open
Our permalinks are set to /%category%/%postname%, but for custom post types we also use the helpful plugin, Permalink Manager Lite. This contains "permastructures" and we use a matching pattern to the "custom rewrite slug" from our custom post type above:
stories/%category%/%stories%
We naturally have a category page for this, in archive-stories.php. This way whether the category was Food, or Fashion, or Home Repairs, the same overall theme works for this custom post type.
The problem lies with Pagination. With some helpful commentary from this website and posts like these, I can now finally see the page numbers.
PROBLEM: Clicking on Page 2 or beyond just gives me the same thing as Page 1.
I used the helpful permalink debug script from Github and it does show me that the "template used" varies across page 1 and 2.
Page 1: /stories/food
Uses the usual category.php (Why? This is a custom post type!)
Page 2: /stories/food/page/2
Uses the more predictable archive-stories.php
Note that these categories are the same across all our website's custom post types. We have custom post types like Stories, Shop, etc. All of them are assigned the same base categories (Food, Style, Home Repairs..).
In both archive-stories.php and category.php (which are currently, for testing, the exact same file), we have the following WP_Query up top:
<?php
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
$args = array(
'post_type' => 'stories',
'orderby' => 'date',
'order' => 'DESC',
'posts_per_page' => 10,
'post_status' => array('publish', 'pending', 'draft'),
'paged' => $paged
);
$the_query = new WP_Query($args);
while( $the_query->have_posts() ) : $the_query->the_post();
?>
......LOOP HERE.....
<?php
// DO THE "TOTAL PAGES" THING
$total_pages = $the_query->max_num_pages;
if ($total_pages > 1){
$current_page = max(1, get_query_var('paged'));
echo paginate_links(array(
'base' => get_pagenum_link(1) . '%_%',
'format' => '/page/%#%',
'current' => $current_page,
'total' => $total_pages,
'prev_text' => __('« prev'),
'next_text' => __('next »'),
));
}
?>
This does show the loop itself well, and it shows the pagination correctly. But clicking page 2 and beyond always shows the exact same page as page 1.
Btw, if we dump the WP_Query() with a print_r($the_query);, we see that the SQL being created is the exact same for both page 1 and page 2, which explains why the page is the same. The "offset" value in LIMIT clause is always 0. On Page 2, this should be 10, on Page 3, this should be 20, etc. We're not sure why it is 0 though.
SELECT SQL_CALC_FOUND_ROWS
wp_posts.ID
FROM wp_posts
WHERE 1=1
AND wp_posts.post_type = 'stories'
AND ((wp_posts.post_status = 'publish' OR wp_posts.post_status = 'draft' OR wp_posts.post_status = 'pending'))
ORDER BY wp_posts.post_date
DESC LIMIT 0, 10
;
If it helps, we notice that we need the following code in functions.php for our /page/2 to work at all, otherwise it throws a 404. This is from the plugin for Category Pagination Fix:
function remove_page_from_query_string($query_string)
{
if (isset($query_string['name']) && $query_string['name'] == 'page' && isset($query_string['page'])) {
unset($query_string['name']);
// 'page' in the query_string looks like '/2', so i'm spliting it out
@list($delim, $page_index) = explode('/', $query_string['page']);
$query_string['paged'] = $page_index;
}
return $query_string;
}
// I will kill you if you remove this. I died two days for this line
add_filter('request', 'remove_page_from_query_string');
// following are code adapted from Custom Post Type Category Pagination Fix by jdantzer
function fix_category_pagination($qs){
if(isset($qs['category_name']) && isset($qs['paged'])){
$qs['post_type'] = get_post_types($args = array(
'public' => true,
'_builtin' => false
));
array_push($qs['post_type'],'post');
}
return $qs;
}
add_filter('request', 'fix_category_pagination');
Many thanks for any pointers!