[wp-hackers] The problem with WP_Rewrite <<< RE: Options for Controller - Views

Mike Schinkel mikeschinkel at newclarity.net
Sat Nov 28 22:24:28 UTC 2009

On Nov 28, 2009, at 2:13 PM, Otto wrote:
> On Sat, Nov 28, 2009 at 6:58 AM, Mike Schinkel
> <mikeschinkel at newclarity.net> wrote:
>> add_custom_url( array(
>>   'name'          => 'product-page',
>>   'url_type'      => 'single-post',
>>   'url_template'  => 'products/{product_slug}',
>>   'template_file' => 'custom/product.php',
>>   'post_type'     => 'product',
>> ));
>> To me that seems very straightforward and is a level of simplicity I think we should strive for, don't you think?
> Yes, but then again no. Basically, you're wanting to combine three
> systems into one, which makes the whole of the system more complex and
> confusing.

> I'm just guessing at what your code does, but to me it appears to:
> a) Create a new rewrite rule for products/whatever.
> b) Push those off into a new template called custom/product.php
> c) Get some kind of special Page data from the database to display there.
> IMO, it's too much. You're overthinking it by trying to multiplex
> everything together. Each piece should be handled separately, and in
> some kind of en masse way.

Yes, you understood what I was trying to accomplish correctly, thanks.

However, I don't understand why you take issue with the need to simplify use of the three subsystems.  Yes, I can see that having them be separated in the core might make sense but I can't see why it would be a bad idea to create a layer that simplifies their use for URL routing when URL routing is something that many people want to do, and do easily.

>> (Wouldn't it be great to have custom URLs addable from the admin console? That's what I think we should have. Also note is assumes a custom post type, the other thing Wordpress badly needs to support in core.)
> Custom post type support is improved in 2.9, although I have not
> examined the new code in detail.

That's awesome.  Can't wait!
>> Now what is (some of) the code I have to write to support that?  Let's take a look:
>> $wp_query->query_vars['page_id'] = 0;
>> $wp_query->is_page = false;  // A "single-post" is not same as a WordPress "Page"
>> $wp_query->is_single = $wp_query->is_singular = true;
>> if ($post_id = self::get_post_id($wp_query)) {
>>   $wp_query->queried_object = $wp_query->post = get_post($post_id);
>>   $wp_query->query_vars['p'] = $post_id;
>> } else {
>>   $wp_query->is_404 = true;
>> }
> A lot of this seems to me to be required only because you're
> attempting to use the existing $wp_query instead of overriding it with
> your own in some fashion. Have you considered doing something along
> these lines instead?
> global $wp_query;
> $wp_query = new WP_Query(array('whatever'=>'XYZ' ...));
> Or even better, just do this:
> query_posts(array('whatever'=>'XYZ' ...));
> I mean, the existing wp_query is basically irrelevant to you, yes?
> You're wanting to get your own page based on your own parameters. So
> just do that and dump the pre-existing query.

Honestly since it's been 6+ months since I last worked on this I can't know for sure whether that will work or not.  I am working on a 3 day developer training course for Wordpress to be delivered Dec 8-10 so I will hopefully get a chance to dig back into that soon to verify.

That said, one big problem I have with it is that I don't want to have Wordpress load a $wp_query and then throw it away only to hit the database a second time.  It's not elegant nor is it good for performance (and caching, while it makes sense to employ, is not a solution for a bad architecture choice.)

Beyond that I seem to remember there were other reasons why that wouldn't work but honestly I can't remember what they are. Like I said I'll try to re-implement soon in order to figure out why.

> Perhaps that is overly simplistic and I need to examine your code
> further. I'll try to get to that on Monday.

I will appreciate that.

>> (what's "is_single" and how does it compare to "is_singular?")
> Single posts only (is_single) vs. any page that shows only a single
> post (is_page or is_single or is_attachment).

I guess the point is that all those switches are overwhelming for most people who are not constantly coding plugins, or mucking with the core.

>> Now I'm not going to suggest if be moved to an MVC; that would be too much for the community to bear.  Instead, I'm simply asking that arbitrary URL routing and post types be added to core as a first class concept; integrated into the core and tested.
> The URL rewriting is already quite capable of that, but directly
> linking that into some kind of template routing system seems to be
> conflating two entirely separate ideas to me. It's unnecessary,
> basically.

It simplifies things, and I thought that was what Wordpress was supposed to be; simple. Right? 

Besides, it doesn't have to be fully conflated in the core, all we need is a layer on top that allows is but leaves the lower level components separate. But that will requiring fixing some of the assumptions in the core that are not easily overridden.
Not having in the core means that it will be very hard to get it fully robust and to ensure the core provides the necessary hooks to fully address the issue.

BTW, the core currently conflates many things that IMO would ideally be separate; Posts vs. Pages, for example.

> All you really need to do is to add a rewrite to pull your
> variable in from the URL, then use a template_redirect to detect that
> variable and call any template you like accordingly. Sure, you could

> make a function to do that all in one stroke, but why?

To make it easier for 99.9% of people. Look out into the wild and ask yourself why so few people are using URL Rewriting on Wordpress sites?  The answer is because it's far to hard to do for the average person.

> It adds unnecessary complexity to the code,

It would add very little complexity to the core if the core where updated to support it.

> and leaves people thinking that rewrites == custom templates, when
> nothing could be further from the truth.

I don't see there's such an aversion to this. People just want to get get something done, not learn all the gory mechanics.

> I took a quick glance at the code (not reading it thoroughly yet) and
> it seems to me that the majority of the complexity lies in your
> modification of the wp_query. Getting the data you need from the posts
> table, basically.

That is correct.  Being able to have URLs rewritten but not being able to have them load the content that need to be loaded does very little good. So addressing one without the other isn't useful.

> The rewriting and template redirection is
> straightforward, albeit you seem to have done it the (very) hard way.
> I'll try to work up a simpler example to show you what I mean.

I'd love to learn an easier way...

>> Sure you can get the URLs to route but the state of Wordpress for those URLs is often the issue. Each URL type wants a different state loaded and Wordpress gets in the way, forcing it's idea of what should be done on you and doesn't give you the choice of what to load.  It *assumes* you are using one of its standard patterns or you are using nothing and that you have to hand-code much of the code run during standard routing that is already in core but not run the way you need it.
> Agreed, WP does indeed want you to do it its own way, however that
> doesn't necessarily mean overriding the existing system with changes.

Not asking to override, just want a simplifying layer on top.

>> Yet discussing one without considering the ramifications on the other two is I believe why you are having problems understanding. The three are not independent in use; they are a holistic three and have to be considered together.
> I really disagree with this, in a big way. Not every rewrite is going
> to use a custom template or load a custom post. Quite the contrary, in
> fact, most rewrites that people want simply change the nature of the
> URL, not the nature of what is loading.

Again, I think you are misunderstanding. Not asking to unify them, asking for another layer to simplify their use *when* it is appropriate.

> Okay. I'm absolutely certain I can create a demo that showcases a
> better way to do these than you're describing. I'll work on it soon.

I look forward to it, and appreciate it in advance.

> But for now, I'm off to get a beer. Happy Holidays!

Enjoy, and ditto.

-Mike Schinkel

More information about the wp-hackers mailing list