Opened 13 years ago
Last modified 7 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
@
13 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
@
13 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.