I’m running into circles trying to set up a simple rewrite rule, and thought I’d run the question by some of the rewrite experts here.
I have a custom post type, “mealplan”, and I’m trying to implement a basic url rewrite where visitng site.com/mealplan/current
will take the visitor to the most recent post of type “mealplan”.
I’ve tried using several variants on this rule:
global $wp_rewrite;
$wp_rewrite->add_rule('mealplan/current',
'index.php?post_type=mealplan&numberposts=1&orderby=date&order=DESC',
'top' );
… but I can’t seem to get either the ‘numberposts’ or the ‘posts_per_page’ parameters to do anything in the query string like that. It just goes straight to the archive page with the default number of posts per page.
This does what I want:
global $wp_rewrite;
$current_mealplan = get_posts( array(
'post_type'=>'mealplan',
'numberposts'=>1,
'orderby'=>'date',
'order'=>'DESC' ) );
$wp_rewrite->add_rule('mealplan/current',
'index.php?post_type=mealplan&post_id='.$current_mealplan[0]->ID,
'top');
…but at the cost of an additional query and a potential flush rules on every page load. Even if I optimize this by saving the current post ID in an option that’s updated on update_post
(so rules only have to be flushed when they change), this feels like unnecessary work that could be avoided if I could only get the url parameters above to work correctly.
Well,
numberposts
is not actually a query variable. It’s just turned intoposts_per_page
inget_posts()
before the query is run.posts_per_page
is a private query var, which means you can’t run it in the query string. A possible solution would be to register a custom query variable (let’s say'latest_mealplan'
and add that variable to the rewrite rule (e.g.index.php?post_type=mealplan&orderby=date&order=DESC&latest_mealplan=1
).Then, hook into
'parse_request'
, which passes the$wp
object to the callback. From there, it’s just a matter of setting the parameter:Hope this helps!