[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