This is what I've used in the past for a similar requirement;
register_post_type('movie', array(
'rewrite' => array('slug' => 'movie')
));
register_taxonomy('movie_location', 'movie', array(
'rewrite' => array('slug' => 'movies')
));
/**
* Add rewrite rules for 'base' archives.
* @param object $r Instance of {@see WP_Rewrite}
*/
function my_custom_rewrite_rules(&$r)
{
$rules = array(
'movies/page/?([0-9]{1,})/?$' => 'post_type=movie&paged=' . $r->preg_index(1),
'movies/?$' => 'post_type=movie'
);
foreach ($rules as &$rule)
$rule = $r->index . '?' . $rule;
$r->rules = array_merge($rules, $r->rules);
}
add_action('generate_rewrite_rules', 'my_custom_rewrite_rules');
See the rewrite
argument in register_taxonomy()
? WordPress automatically creates the appropriate rewrite rules, including archive pagination!
Also note the singular use of movie
in the register_post_type()
rewrite
argument - partly because, IMO, it's semantically correct, but more so that you don't open up a whole can of worms.
What's that can of worms exactly?
Well, otherwise you'll end up with two rewrite rules like so;
'movies/([^/]+)/?$' => 'post_type=movie&movie_location=$matches[1]'
'movies/([^/]+)/?$' => 'post_type=movie&name=$matches[1]'
Whichever one is indexed first in the rewrite rules array will always be triggered, and the other one ignored.
So say you've a got a movie named made-in-britain
, but the rewrite rule for the taxonomy archive comes first, WordPress is always gonna look for movies with the made-in-britain
term, rather than the movie itself!