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

Otto otto at ottodestruct.com
Thu Dec 3 16:04:56 UTC 2009


On Sat, Nov 28, 2009 at 4:24 PM, Mike Schinkel
<mikeschinkel at newclarity.net> wrote:
>> 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.

Mike,

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

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');

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

add_rewrite_tag lets the post_type variable exist and sets it in the
query_vars and such. Also ensures that it gets set in the global
$wp_query.

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.

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.

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');


If I wanted it to get a specific post instead, I'd have used 'post_id'
instead of post_type. Since post_id is already one of the rewrite
tags, I could leave off the add_rewrite_tag call for that, but add a
new one for the special product variable. That would look something
like this:
add_rewrite_rule('products/(.*)[/]?$',
'index.php?post_id=12345&product=$matches[1]', 'top');
add_rewrite_tag('%product%','.*');

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.

-Otto
Sent from Memphis, TN, United States


More information about the wp-hackers mailing list