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

Mike Schinkel mikeschinkel at newclarity.net
Thu Dec 3 16:37:07 UTC 2009


> I said before that I'd give you a simple example. This might be too
> simple, but it should explain a few things.

Thanks for giving some concrete examples.

> function plugin_add_custom_urls() {
>  add_rewrite_rule('products/(.*)[/]?$',
> 'index.php?post_type=$matches[1]', 'top');
>  add_rewrite_tag('%post_type%','.*');
> }
> add_action('init', 'plugin_add_custom_urls');

First, that's far more complicated than it should be if this is something people will be doing a lot. But let's ignore that for a moment.

> add_rewrite_rule adds the rewrite rule to do products/whatever. The
> "whatever" gets set to the post_type query variable.

Unless I misunderstand, that's not I'm looking for.  Using your example, this might be what I'm looking for (not sure about the "add_rewrite_tag()" as I don't really understand what it does):

function plugin_add_custom_urls() {
 add_rewrite_rule('products/(.*)[/]?$',
'index.php?post_type=product&pagename=$matches[1]', 'top');
 add_rewrite_tag('%post_type%','.*');
}
add_action('init', 'plugin_add_custom_urls');

I can't test any of this at the moment because I upgraded MySQL and it blew away all my databases. Grrr.

> Now, because wp_query already supports post_type as an input
> parameter, I don't have to change anything along those lines. If it
> didn't, I'd have to add a filter hooked to 'posts_where' to add the
> additional where clause.

Can I assume that post_type is not supported until 2.9?  It doesn't seem to work in 2.8 (which is what I'm working with.)

I'm okay to delay solutions to 2.9 since it's imminent, but want to make it clear the simple option you propose wasn't available 6 months ago when I wrote my plugin.

> But, the resulting query SQL that this generates is this:
> SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  WHERE 1=1  AND
> wp_posts.post_type = 'whatever' AND (wp_posts.post_status = 'publish'
> OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private')
> ORDER BY wp_posts.post_date DESC LIMIT 0, 10
> 
> Note that it's selecting on wp_posts.post_type='whatever', which is
> something I think you wanted to do.

And that is all great.  It's what I really wanted to happen when I was working on it 6 months ago.

> You also wanted to redirect to a specific custom template based on
> this, I believe. That would be along these lines:
> 
> function plugin_add_template() {
>  if (get_query_var('post_type') == 'whatever') {
>    locate_template(array('custom/product.php'),true);
>    exit;
>  }
> }
> add_action('template_redirect', 'plugin_add_template');

Again, too complex for doing often.  But let's hold that thought too...

> Now, in my template redirection function, I could do
> get_query_var('product') and act accordingly. Since we set the
> post_id, the wp_query we get there is going to have the post with ID
> 12345, unless I add more filters to modify its contents.
> 
> Does this help explain things a bit better? I know it's not a complete
> example, but these seem to accomplish your goals to me. They add a
> rewrite, let you modify the query a bit, and provide you with a custom
> template. You could wrap them in a function to make them easier to
> call as well, I suppose.

It helps yes.  OTOH, it's not much different from what I did before in that it seems to be leveraging 2.9 functionality I had no access to in 2.8.

Also, it requires a level of complexity that few if any theme developers will go to.  Themers *will* be willing to use a simplifying layer like what I showed with add_custom_url() and I strongly believe such a functionality is needed.  Yes it will not cover every potential use case as the lower level examples can but it will cover the most common use cases and make them very easy to implement.

I'll try to implement add_custom_url() on the 2.9 platform and submit it as a patch soon.

-Mike


More information about the wp-hackers mailing list