Parts of this are easy, and parts of this are not so easy. It depends on how complete of a solution you're looking for. Fixing the native pagination functions, for example, is probably more effort than it's worth. The problem is the fact that "page 0" and page 1 are the same page is baked into the code.
Anyway, the first step is to stop WordPress from redirecting from /post/1/
to /post/
. This is fairly straightforward, using the redirect_canonical
filter. Here we check if it's a singular post and the page number is 1. In that case, we return false
to prevent the redirect, otherwise we return the redirect URL untouched.
function wpd_disable_page1_redirect( $redirect ) {
if( is_singular('post') && ( 1 == get_query_var( 'page' ) ) ){
return false;
}
return $redirect;
}
add_filter( 'redirect_canonical', 'wpd_disable_page1_redirect' );
You also have to modify the canonical URL that prints in the document head
on the new "first page":
function wpd_page1_canonical( $canonical_url, $post ) {
if( is_singular('post') && ( 1 == get_query_var( 'page' ) ) ){
return $canonical_url . '1/';
}
return $canonical_url;
}
add_filter( 'get_canonical_url', 'wpd_page1_canonical', 10, 2 );
So now the page numbers work, but aside from the landing page, the wrong content is shown.
To fix that, we can use the content_pagination
filter. This gives us access to the individual pages that were parsed from post content, in the form of an array. We can shuffle pages around, and add or remove them. The simplest fix for our purposes is to shift the whole array over by one element if we're on any page other than the landing page:
function wpd_content_pagination_filter( $pages, $post ){
if( 1 < count( $pages ) && get_query_var( 'page' ) ){
array_shift( $pages );
}
return $pages;
}
add_filter( 'content_pagination', 'wpd_content_pagination_filter', 10, 2 );
But this again highlights the underlying problem- we have a different number of pages getting returned in our array. We could do things a bit differently and fix that (by making it wrong in a different way), but there has to be a compromise somewhere, since lots of native functions think 0 and 1 are the same page.
There are certainly some details I've missed here, like handling "ugly" permalinks, a "phantom" last page you can manually paginate to, and, of course, pagination, but hopefully this should get you on your way.
"Sorry our content is not available in your area. We hope to be live in your area soon!!"