Opened 14 years ago
Last modified 8 years ago
#19493 new defect (bug)
post and archive pagination don't work with custom endpoints
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | 2.1 |
| Component: | Rewrite Rules | Keywords: | needs-patch |
| Focuses: | Cc: |
Description
Archive pagination and post pagination are not endpoint-aware, so they break when endpoints are added to them.
The following example code creates an endpoint, and then uses a filter to add that endpoint to various links on the rendered page:
add_action( 'init', function() {
global $wp_rewrite;
add_rewrite_endpoint( 'foo', EP_ALL );
$wp_rewrite->flush_rules(false);
} );
add_filter( 'post_link', 'gist_add_endpoint_to_url', 99 );
add_filter( 'get_pagenum_link', 'gist_add_endpoint_to_url', 99 );
function gist_add_endpoint_to_url( $url_base ) {
$endpoint = 'foo';
$url_parts = parse_url( $url_base );
$url = ( isset($url_parts['scheme']) && isset($url_parts['host']) ) ? $url_parts['scheme'] . '://' . $url_parts['host'] : '';
$url .= isset($url_parts['path']) ? $url_parts['path'] : '';
$url = user_trailingslashit( $url );
if ( '' === get_option('permalink_structure') ) {
$url .= isset($url_parts['query']) ? '?' . $url_parts['query'] : '';
$url = add_query_arg( $endpoint, 'true', $url );
} else {
$url .= $endpoint . '/true';
$url = user_trailingslashit( $url );
$url .= isset($url_parts['query']) ? '?' . $url_parts['query'] : '';
}
$url .= isset($url_parts['fragment']) ? '#' . $url_parts['fragment'] : '';
return $url;
}
You'll see that it works perfectly using the theme unit test, except that paginated posts produce URLs like this:
βhttp://example.com/2008/09/layout-test/foo/true/2/
...which doesn't work. The inverse -- βhttp://example.com/2008/09/layout-test/2/foo/true/ -- also doesn't work, and produces a 404 on top of it.
Also, the older posts / newer posts produce this format of link:
βhttp://example.com/page/2/foo/true/
.. .which also doesn't work.
If you change gist_add_endpoint_to_url() to add a querystring param, older posts/newer posts links work fine, but post pagination still breaks:
function gist_add_endpoint_to_url( $url_base ) {
$endpoint = 'foo';
$url_base = add_query_arg( $endpoint, 'true', $url_base );
return $url_base;
}
If you don't use a permalink structure at all, it works fine, since the pagination params are passed directly in the URL.
I'm not sure if the fix lies in modifying add_rewrite_endpoint() so that it creates pagination urls in wp_rewrite, or modifying the way _wp_link_page() and get_next_posts_link() work.
Change History (11)
#3
@
14 years ago
- Cc Ken@β¦ added
I was working from a variation of westi's code from βhttp://core.trac.wordpress.org/ticket/16303#comment:1 and the json endpoint breaks on paged urls: example.com/json/ works, and example.com/page/2/ works, but example.com/page/2/json/ fails has_posts() because $wp_query contains query->attachment and query_vars->attachment are set to "2" for some reason in addition to json being set true.
Pretty sure this is related? Fits the title at least.
#4
@
14 years ago
Further, ?paged=3&json=1 gets redirected to /page/3/?json=1 which works correctly (returns JSON).
Also, /page/3/garbage/ returns paged=1 but without stickies and 404 title (which has nothing to do with endpoints), and /page/3/something/json returns JSON but with the query attachment: "something" (and json: true) while using non-permalink vars (/?paged=3&something&json/) work as expected (turns into /page/3/?something&json/).
I don't fully understand how the permalink parsing works, so I can't tell if this is expected or bugged, but to the permalink layperson, this seems unexpected and buggy.
I never understood what the difference between endpoints and permastructs was.