[wp-hackers] The problem with WP_Rewrite <<< RE: Options for Controller - Views
mikeschinkel at newclarity.net
Thu Dec 3 04:24:26 UTC 2009
On Nov 29, 2009, at 1:46 AM, Dion Hulse (dd32) wrote:
> For everyones benefit, i've just written a quick plugin which achieves what you set out to do with the product rewrite rules, whilst reducing the ammount of useless SQL queries performed as well as avoiding some rather messy code:
> In a nutshell:
> * 3 filters to control Rewrite, Query, and Template
> * No eronous SQL queries, The only query is the product load query. (I'm refering to post queries here btw)
> * Works with WordPress 2.9, 2.8 should work too
> * Fair bit of comments inline, Not finished obviously
> * Takes /products/<slug> and spits out post_type = product
> * Works no matter what your permastructure is ( none, ie. ?product=product-1, /product/product-1/, /index.php/product/product-1/)
> * Admin panel to add/remove products
> * 2 lines which i would call hackish.. But thats only telling wordpress that we're on a custom page.. (is_single = true, is_home = false)
> * Uses a custom page template bundled with the plugin (Taken from single.php from default theme, removed a bit of code, bare basics)
> * Uses as much of the API as currently exists for it.
> * Not finished 100%, Final few touches need to be put on, such as flushing of rules on deactivation
> Yes, This is not a complete writeup, Its just to demonstrate, that the code does not have to be as messy as you've quoted, And while its longer and more verbose than add_cusotm_url(), its definately a better start.
So I finally had a chance to review this. I'm working with it on 2.8.6.
While it may "do it right" it actually doesn't work, for at least two reasons. (Dion, did you actually test it? Did it even work in 2.9?)
1.) The plugin treats parse_query as a filter yet it's run as an action. Returning a modified request does nothing. (Should it be run as a filter instead of an action? Most probably. But we can at least work around it temporarily.)
2.) More importantly $wp->handle_404() [line 459 in /wp-includes/classes.php] basically blocks anything that's not previously been hardcoded into WordPress core. To get around it you have to do some ugly hacks. My prior plugin accomplished it but the "HTDIR" plugin did not.
Maybe the first thing to discuss is "How should $wp->handle_404() be modified to support URL rewriting?" As a strawman, I propose the following (please suggest better ways of handling this.)
On line 462 of /wp-includes/classes.php insert the following three lines of code:
With that and some hacking in the parse_query function to set $wp_query to the modified as well as set $wp_query->is_404 to false and $wp_query->is_product to true, and implementing a handle_404 hook I was able to get the basics of URL rewriting to work from Dion's HTDIR plugin although I haven't fleshed out any of the other aspects of the custom post types use cases.
BTW, I just checked and trunk for 2.9 hasn't modified $wp->handle_404() since 2.8.6 so this is still an issue.
P.S. BTW, the whole $wp_query->is_* variable thing is not scalable and IMO all those $wp_query->is_* properties are one of the reasons WP code is hard to follow and bloated in its own right. I wouldn't want to see us proliferate them even more; I used $wp->is_product simply because Dion had used it and I was going for as few changes as possible.
More information about the wp-hackers