I created myfile.php
with the following content:
global $paged;
if ( get_query_var( 'paged' ) ) {
$paged = get_query_var( 'paged' );
} else if ( get_query_var( 'page' ) ) {
$paged = get_query_var( 'page' );
} else {
$paged = 1;
}
$args = array(
'post_type' => array('my_custom_post_type'),
'paged' => $paged,
'posts_per_page' => 3,
'ignore_sticky_posts' => 1
);
$wp_query = new WP_Query( $args );
var_dump($wp_query);
if($wp_query->have_posts()) :
while($wp_query->have_posts()) : $wp_query->the_post();
// show post
endwhile;
endif;
next_posts_link('Next posts');
wp_reset_query();
wp_reset_postdata();
and:
- when it’s set to “Static Front Page” in Settings > Reading it works fine with pagination. I can access http://example.com/page/2
- when Settings > Permalinks is set to “Default Permalinks Structure” it works with http://example.com/?page_id=1234&paged=2
- when Settings > Permalinks is set to any “Custom Structure” the following http://example.com/mypage/page/2 launches 404.php.
I have no idea what am I missing here but I just tried every single suggestion from troubleshooting guide on this page: https://codex.wordpress.org/Pagination – they suggest that “404 – not found” is one of the common problems when the permalinks are set to “Custom Structure” so WP developers are aware of some bug or issue but they don’t say how to fix that.
My server is WAMP for Windows 7 (PHP 5.4.3, Apache 2.4.2, mod_rewrite
enabled, custom link structures work great expect pagination when “myfile.php” is used as a page other than “Static Front Page”).
My .htaccess when “Custom Permalink Structure” is set to “Post name”:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wp/index.php [L]
</IfModule>
# END WordPress
When I enter http://example.com/mypage/page/2 (doesn’t work): SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_name = 'page' AND wp_posts.post_type = 'my_custom_post_type' ORDER BY wp_posts.post_date DESC
When I enter http://example.com/?page_id=1234&paged=2 (works): SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'my_custom_post_type' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 2, 2
I’ve experienced this with several plugins of my own, while trying to display a numerical pagination for my custom post types and custom taxonomies.
It’s my understanding that by using
WP_Query
to fetch posts from the database in your own custom way (other than the default) will prevent you from using such functions as expected.They’re intended to be used for the default posts query. So if you would like to use those functions as intended, then you’ll need to modify the default query BEFORE the query is performed. You can do this using the hook
pre_get_posts
.However, if you would like to use your own custom query using
WP_Query
, then you’ll need to also customize how the numerical pagination works. You can get the same net result using standard WordPress functionality, but it requires a few extra lines of code to achieve the numerical pagination as expected.Let’s say you have a custom query using
WP_Query
and it looks something like this:$query = new WP_Query( $query_args );
This means you have a completely BRAND NEW query which is different than the main default query which is performed when the page is loaded.
Now WordPress is aware of TWO queries for the current page:
WP_Query
.If you want your numerical pagination to work with your custom query, then you need to be aware of the current page the request is performed on.
The current page number is actually referred to as
paged
. You can determine the current page number using some code like this:Once the current page has been determined, you can setup your custom query to look similar to this:
Once the query has been performed, you then need to check if it’s located any posts in the database which match your criteria:
Now for the numerical pagination! I recommend using a WordPress function called
paginate_links()
for this part.I don’t really understand the really unlikely integer part for the
base
, but that’s what’s demonstrated on the WordPress Codex page linked above.paged
) — once again.from the
$query
variable object).like it to be in array format, so that I can customize the pagination
however I see fit).
This code needs to be placed within the condition which states that we have posts available. Not inside the loop, but immediately AFTER the loop.
Once the numerical pagination has been configured, it’s ready for output (or ready to be displayed). This is where paginated items are returned in
array
format.I like to wrap it with a conditional check and then loop through the items performing additional conditional checks along the way.
Note: I use Bootstrap for my WordPress themes. So if you want your pagination to look awesome, with minimal effort involved. Try out Bootstrap.
To conclude everything mention above, here’s a all-in-one copy/paste starter solution for anyone looking to create a numerical pagination with a custom posts query using
WP_Query
.You can also try below code.
After hours of struggling I found the cause.
The post type that I registered using
register_post_type( 'my_custom_post_type', array( ... ) );
had'rewrite' => array( 'slug' => 'my_custom_post_type' )
. That was taking priority over pagination and that’s why “404 – not found” was happening.If anyone has better explanation of what takes priority and when, please edit my answer. This issue is resolved after editing
rewrite
to something else.