#16303 closed defect (bug) (fixed)
Improve documentation and usability of WP_Rewrite Endpoint support
Reported by: | westi | Owned by: | westi |
---|---|---|---|
Milestone: | 3.7 | Priority: | lowest |
Severity: | normal | Version: | 3.1 |
Component: | Rewrite Rules | Keywords: | westi-likes has-patch commit dev-feedback needs-docs |
Focuses: | Cc: |
Description
When you know how it works the WP_Rewrite Endpoint support is really simple and cool.
When you don't it looks really difficult to use.
We should document it better and add an endpoint mask for Custom Post Types.
Attachments (4)
Change History (32)
#3
@
14 years ago
- Keywords westi-likes added; 3.2-early removed
- Milestone changed from Future Release to 3.2
- Priority changed from normal to lowest
Although not a roadmapped 3.2 feature this is a really simple patch which makes the existing functionality much easier to understand and proves how useable it actually is.
So I really want to put this in 3.2 - low priority though
#4
@
14 years ago
- Cc mikeschinkel@… added
@westi - I'd really like to understand the API endpoint functionality but thus far can't grok it. Has it been documented yet? Google fails me. Any chance of a short-term Cliff Notes version?
#5
follow-up:
↓ 8
@
14 years ago
mikeschinkel: It's actually very simple.
You register a "Endpoint" with a Endpoint Mask.
add_rewrite_endpoint( 'json', EP_ROOT ^ EP_PERMALINK ^ EP_ALL_ARCHIVES );
If you understand Binary mathematics, it's a lot easier, as it's using Bitwise comparisons ( this site seems to give a reasonable overview of it)
Each set of rewrite rules that is generated by core is given a Endpoint Mask(a bitmask), for example, posts get EP_PERMALINK, If the bits set in EP_PERMALINK is "equal to" the bits in the specified endpoint mask, then that endpoint is added to the rules generated.
Note, that Custom Post Types by default get given _no_ endpoint mask, you can set it when you register the post type, but for best results, it should be a unique number (well, power of 2) global to the install, this is a bit hard to track and I've personally just ended up using stupidly high numbers (240 for example) as masks.
westi: That patch looks like it's missing a file? You've defined the bitmask, but never actually used it?
#6
follow-up:
↓ 7
@
14 years ago
Just reviewd the patch and refreshed against trunk, my 2 cents:
- As written in comments, the Bitmask is OR'ed. That's what common as well (PHP Example)
- There is no vartype "bitmask" (isn't it int?, see notes)
- Adding an endpoint does always mean a new endpoint (tautological).
- It's 3.2.0 now.
Additional notes:
- EP_ALL can be safely defined as 16 383, that spares the calculation.
- Same for EP_ALL_ARCHIVES, can be pre-calculated as well (documentation could show what value stands for)
- About the missing use of the define dd32 was pointing westi to I have no clue.
westi: WP_Rewrite::add_endpoint() had documented the $places
as an array, you changed that to bitmask (and I to int because I think bitmasks are ints). What PHP vartype is that $places
parameter of the said function?
#7
in reply to:
↑ 6
@
14 years ago
Replying to hakre:
Additional notes:
- EP_ALL can be safely defined as 16 383, that spares the calculation.
This was changed on purpose to ease maintenance and to hilight to people reading the code that it wasn't a static value and could change.
- Same for EP_ALL_ARCHIVES, can be pre-calculated as well (documentation could show what value stands for)
All "Archive" type pages
- About the missing use of the define dd32 was pointing westi to I have no clue.
The define is added but not used as it's really useful for plugins :)
westi: WP_Rewrite::add_endpoint() had documented the
$places
as an array, you changed that to bitmask (and I to int because I think bitmasks are ints). What PHP vartype is that$places
parameter of the said function?
bitmasks are ints yes - I was just being more specific.
Take note all the code in my original patch was written on a transatlantic flight :)
#8
in reply to:
↑ 5
@
14 years ago
Replying to dd32:
Thanks for attempting to explain. I'm familiar with bitwise math (learned it well in my assembler class in college) it's just that I don't understand what happens when each of the following masks are used. What does EP_ROOT
imply? Or EP_PERMALINK
? Or EP_ALL_ARCHIVES
?
Thanks in advance.
#12
@
13 years ago
Shouldn't CPTs add their own endpoint masks? Or is this for the CPT archive only?
#13
@
13 years ago
- Keywords dev-feedback added
I don't see any clear resolution here, and we're at freeze for 3.3. Leads/committers, please weigh in on the commit vs punt decision.
#15
@
13 years ago
I was looking at the documentation for rewrite.php in general and I remembered this ticket. 16303.ep-docs.diff was my attempt at some better inline documentation for endpoints.
In documenting this I noticed some strange behaviour with the endpoint code given in my example, see #19876.
#17
follow-up:
↓ 18
@
13 years ago
- Keywords 3.3-early removed
I attached a new version of the improved functionality patch.
However, there are a couple of issues:
- Should EP_ROOT be included in EP_ALL_ARCHIVES? It depends on the page_on_front option as to whether or not it's an archive.
- Is EP_CPT_ARCHIVE usable? This was alluded to in previous comments. register_post_type() uses WP_Rewrite::add_rule() when creating rewrites for CPT archives, and this means no endpoints.
#18
in reply to:
↑ 17
@
13 years ago
Replying to duck_:
I attached a new version of the improved functionality patch.
However, there are a couple of issues:
- Should EP_ROOT be included in EP_ALL_ARCHIVES? It depends on the page_on_front option as to whether or not it's an archive.
- Is EP_CPT_ARCHIVE usable? This was alluded to in previous comments. register_post_type() uses WP_Rewrite::add_rule() when creating rewrites for CPT archives, and this means no endpoints.
I don't think that the ROOT of the site is ever an archive view really (and it people want to include it they can OR it in) I think have different behaviour for / not for page on front could be confusing and would mean we would need to flush and regen rules if the option changed.
I'm not sure if EP_CPT_ARCHIVE is currently usable but it is something that I feel should be usable - use case something like the example JSON endpoint above would automatically get a JSON version of any CPT archive view if it works ( I can't remember how I tested at the time but I can probably dig the code out - I was working around the concepts of a Person CPT with the CPT Archives be "People")
#19
follow-up:
↓ 20
@
13 years ago
- Cc luke.gedeon@… added
Here is another example that might help with documenting end-points:
This code adds an endpoint of the form /embed/xxxx/ to the end of any post. We then load a separate template to render the article in one of several embeddable formats.
class plugin_embeddable_post { public function __construct() { add_action( 'admin_init', array( $this, 'admin_init' ) ); add_filter( 'query_vars', array( $this, 'query_vars' ) ); add_filter( 'template_include', array( $this, 'template_include' ) ); } /** * add_rewrite_endpoint just adds an endpoint to the pool of endpoints that * will be used when generate_rewrite_rules is run. It does nothing on it's * own but generate_rewrite_rules fires too late, so we use admin_init to * make sure it is there when rules are flushed. */ public function admin_init() { add_rewrite_endpoint( 'embed', array( EP_PERMALINK ) ); } public function query_vars( $public_query_vars ) { $public_query_vars[] = 'embed'; return $public_query_vars; } public function template_include( $template ) { if ( 'format1' == get_query_var( 'embed' ) ) $template = locate_template( 'embed-format1.php' ); // add additional embeddable formats here or use one template for all return $template; } } $plugin_embeddable_post = new plugin_embeddable_post;
#20
in reply to:
↑ 19
@
13 years ago
Replying to lgedeon:
Here is another example that might help with documenting end-points:
This code adds an endpoint of the form /embed/xxxx/ to the end of any post. We then load a separate template to render the article in one of several embeddable formats.
Just a couple of notes:
- You shouldn't pass an array as $places to add_rewrite_endpoint(). AFAIK the binary representation of an array is "1" so it works for EP_PERMALINK, but try the same code but with EP_PAGES and it will still add the endpoint to post permalinks. This was a documentation error previously.
- WP_Rewrite::add_endpoint() will add the query var for you. I guess that since you're hooking into admin_init to add_rewrite_endpoint() it's not going to work unless you hook into init instead.
#21
@
13 years ago
Hi duck_
Thanks for the feedback. I wrote this before the documentation update and missed that when I copy/pasted. BTW, thank you so much for updating the docs. This is a really cool feature and the doc helps make it available to more devs.
I did see that add_rewrite_endpoint() adds the query_var but since I only need to call add_rewrite_endpoint() when rewrite rules are flushed and need the query var all the time, it almost makes sense to split them. The other option as you mentioned is to call add_rewrite_endpoint() all the time, on init. The function is light enough that it probably wouldn't hurt. I just had not decided yet... so I did half of both. :)
A json endpoint example: