I’ve a very simple index.php
:
<div id="content">
<? get_template_part('content', get_post_format()) ?>
</div>
<div id="pagination">
<? previous_posts_link() ?>
<? next_posts_link() ?>
</div>
And my content.php
looks roughly like this:
<?
$paged = get_query_var('paged') ? get_query_var('paged') : 1;
query_posts([
'post_type' => ['articles', 'projects', 'tips'],
'orderby' => 'date',
'posts_per_page' => 7,
'paged' => $paged
]);
?>
<? while(have_posts()): the_post() ?>
<article class="post">
<h2><? the_title() ?></h2>
<p><? the_excerpt() ?></p>
<ul>
<? foreach($categories as $cat): ?>
<li class="category"><a href="#"><?= $cat->name ?></a></li>
<? endforeach ?>
</ul>
</article>
<? endwhile ?>
There are 14 posts in total but the “next” posts is always redirecting to a 404 on /page/2
instead of showing the remaining 7 posts.
Edit: If I use a custom WP_Query
instead of query_posts
then the next and previous links won’t even show. https://gist.github.com/elclanrs/4782705
I’ve been trying to find a solution to this issue since yesterday. I’m aware of all the other questions similar to this one, but for my particular set-up none of the solutions I found worked, including:
- http://wordpress.org/support/topic/pagination-with-custom-post-type-listing
- http://www.rjust.com/2011/03/22/fix-previous_posts_link-and-next_posts_link-for-custom-post-types/
- Make sure that “Blog pages show at most” matches
posts_per_page
I’m also aware of pre_get_posts
but I would like to know what’s the problem with my current setup. Any ideas?
By the time you reach the template, WordPress has already queried the database and decided what to display based on those results.
You’re seeing a 404 error because based on the default main query, there are no more posts to show.
When you call
query_posts
in the template, you overwrite that original query. Despite the fact that your new query results contain more posts, WordPress has no awareness of this modified query.This is why you should never use
query_posts
in the template. You’ve provided the solution to your issue already, use thepre_get_posts
action to modify the main query before it happens.Another solution that worked for me if using the Custom Post Type UI plugin, was to alter the rewrite settings in the interface for the custom post type.
For example, I had a custom ‘news’ post type, no issues other than pagination wouldn’t work (e.g. /news/page/2 would 404). The two solutions I found were to either:
Ultimately, though, I imagine the above is just a fix if your listing page is called the same as your post type. E.g. the page by ‘news’ post type was showing on, had the slug ‘news’ too so this could have confused matters.