1

I'm using add_rewrite_rule() to create a custom endpoint:

  • example.com/author/username/my-endpoint

I need pagination on this page because I'm displaying a list of users using WP_User_Query. When I visit these URLs I see the users I should be seeing so everything appears to be working:

  • example.com/author/username/my-endpoint/
  • example.com/author/username/my-endpoint/page/2/
  • example.com/author/username/my-endpoint/page/3/ etc

The problem: when I visit the network tab in Chrome Dev Tools when viewing the paginated pages (my-endpoint/page/2/ and my-endpoint/page/3/ etc), it tells me WordPress is returning a 404.

Here's the full code I'm using:

// Add query var.
add_filter( 'query_vars', function( $vars ) {
    $vars[] = 'my-endpoint';
    return $vars;
} );
// Add rewrite rules.
add_rewrite_rule(
    '^author/([^/]+)/my-endpoint/page/([0-9]+)/?$',
    'index.php?author_name=$matches[1]&my-endpoint=1&paged=$matches[2]',
    'top'
);
add_rewrite_rule( 
    '^author/([^/]+)/my-endpoint/?$', 
    'index.php?author_name=$matches[1]&my-endpoint=1', 
    'top'
);
// Template display
add_filter( 'template_include', function( $template ) {
    global $wp_query;

    if ( array_key_exists( 'my-endpoint', $wp_query->query_vars ) ) {
        return trailingslashit( get_template_directory() ) . 'my-endpoint.php';
    }
    return $template;
} );
// The user query in my my-endpoint.php template.
$page = max( 1, get_query_var( 'paged' ) );
$args = array(
    'count_total' => true,
    'include'     => $ids,
    'number'      => get_option( 'posts_per_page' ),
    'offset'      => ( $page - 1 ) * get_option( 'posts_per_page' ),
    'order'       => 'DESC',
    'orderby'     => 'include',
    'paged'       => $page
);
$wp_user_query = new WP_User_Query( $args );

Why is WordPress returning a 404 on paginated pages?

  • example.com/author/username/my-endpoint/page/2/
  • example.com/author/username/my-endpoint/page/3/ etc

Update

I tried using my own query var as suggested in the answer below but I continue to see the 404:

// Add query var.
add_filter( 'query_vars', function( $vars ) {
    $vars[] = 'my-endpoint';
    $vars[] = 'userpaged';
    return $vars;
} );
// Add rewrite rules.
add_rewrite_rule(
    '^author/([^/]+)/my-endpoint/userpaged/([0-9]+)/?$',
    'index.php?author_name=$matches[1]&my-endpoint=1&userpaged=$matches[2]',
    'top'
);
0

You get a 404 because you use the wordpress paged query var, and therefor wordpress tries to locate in the main query that page for that user, and if the user is not an author, or just havn't published anything, there will be no posts for that page and wordpress will set the headers to 404.

Easy solution, make additional query var for your own paging.

Thinking a little more deeply into it... you will probably want to use the status_header, called from https://developer.wordpress.org/reference/functions/status_header/ in any case to modify the status header being sent, as there might be cases in which the user pagination gives empty results while the main loop will find something.

The tricky part is to know what should be the status way before any output is done, therefor waiting to get to template usage is too late and needs to be done when the main query is being "computed", so probably at pre_get_posts filter, even you do not need to change anything in the main query.

  • Thanks for the suggestion. I tried using my own query var (see my update above) but I continue to see the 404. – henrywright May 25 '17 at 12:52
  • hmm (useful but) wrong filter. will a mend the answer in a sec – Mark Kaplun May 25 '17 at 13:10
  • as for why you still got a 404, with using a new paging var, it might be because the user was not an author, or have no associated posts – Mark Kaplun May 25 '17 at 13:17
  • None of my users returned by the query have posts. That could explain the 404 because the main query is finding no 2nd, 3rd, 4th page etc. – henrywright May 25 '17 at 13:23
  • The main query is for posts and my custom query (which I need pagination for) is for users. That seems to be the problem. – henrywright May 25 '17 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.