You have 2 problems.
First problem
The line
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
will fail, because on singular post view, when the URL contains '/page/XX/', the variable WordPress sets is 'page' and not 'paged'.
You may think to use 'page' instead of 'paged', but that will not work either, because once the 'page' variable is intended to be used for multi-page singular post (page separation using <!--nextpage-->) and once the post is not multi-page, WordPress will redirect the request to the URL without '/page/XX/'.
This is what happens when you name your query variable $wp_query.
The solution is to prevent that redirection by removing the function responsible for it, which is 'redirect_canonical' hooked into 'template_redirect':
So, in your functions.php add:
add_action( 'template_redirect', function() {
if ( is_singular( 'authors' ) ) {
global $wp_query;
$page = ( int ) $wp_query->get( 'page' );
if ( $page > 1 ) {
// convert 'page' to 'paged'
$wp_query->set( 'page', 1 );
$wp_query->set( 'paged', $page );
}
// prevent redirect
remove_action( 'template_redirect', 'redirect_canonical' );
}
}, 0 ); // on priority 0 to remove 'redirect_canonical' added with priority 10
Now WordPress will not redirect anymore and will set correctly the 'paged' query var.
Second problem
next_posts_link() and previous_posts_link() both check if ( ! is_single() ) to display pagination.
Now, is_single() is true in your case, because you are in a single post of ‘author’ type, so those functions can’t work as you expect.
You have 3 possibilities:
- Use
query_poststo override the main query (really not recommended) - Use a custom page template instead of a custom post type, because
is_single()is false for pages, and your code will work there. - Write your own pagination function and use that
That’s the code for solution number #3:
function my_pagination_link( $label = NULL, $dir="next", WP_Query $query = NULL ) {
if ( is_null( $query ) ) {
$query = $GLOBALS['wp_query'];
}
$max_page = ( int ) $query->max_num_pages;
// only one page for the query, do nothing
if ( $max_page <= 1 ) {
return;
}
$paged = ( int ) $query->get( 'paged' );
if ( empty( $paged ) ) {
$paged = 1;
}
$target_page = $dir === 'next' ? $paged + 1 : $paged - 1;
// if 1st page requiring previous or last page requiring next, do nothing
if ( $target_page < 1 || $target_page > $max_page ) {
return;
}
if ( null === $label ) {
$label = __( 'Next Page »' );
}
$label = preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&$1', $label );
printf( '<a href="https://wordpress.stackexchange.com/questions/143812/%s">%s</a>', get_pagenum_link( $target_page ), esc_html( $label ) );
}
and use it like so in the single-authors.php:
my_pagination_link( 'Older Entries', 'next', $author_query );
my_pagination_link( 'Newer Entries', 'prev', $author_query );