Ever wondered about WordPress custom URL rewrites? Here I was dealing with an interesting problem. I wanted to add a rewrite rule on a permalink and wanted to use a custom template for that rewrite rule. However, this is not an exhaustive post about how to do rewrite rules, there is a very good detailed tutorial about this if you want to know more details.
Objective:
- Add a rewrite rule on a custom post type permalink
- Use a page template based on the rewrite rule
Here we have a movie
post type. The permalink structure is movie/{movie-name}
. I want to append a photos
and videos
endpoint to that url, so the structure will be movie/{movie-name}/photos
and movie/{movie-name}/videos
. As you can guess, I want to show all the photos and videos on a separate page from that movie and want to use separate page template to accomplish this.
1. Register Custom URL
function prefix_movie_rewrite_rule() { add_rewrite_rule( 'movie/([^/]+)/photos', 'index.php?movie=$matches[1]&photos=yes', 'top' ); add_rewrite_rule( 'movie/([^/]+)/videos', 'index.php?movie=$matches[1]&videos=yes', 'top' ); } add_action( 'init', 'prefix_movie_rewrite_rule' );
By this add_rewrite_rule
function, we are adding two custom rewrite rules to the URL and setting two query variables to the URL. I am not using add_rewrite_endpoint
because I don't want to add this endpoint to every permalink I have. But by only adding this rewrite rule they won't work and WordPress will reject them because it doesn't recognize those query vars we added via our rewrite rule function. We have to tell WordPress to be modest on these query vars.
2. Register Query Vars
function prefix_register_query_var( $vars ) { $vars[] = 'photos'; $vars[] = 'videos'; return $vars; } add_filter( 'query_vars', 'prefix_register_query_var' );
Now, as we've added those query vars to WordPress, it will recognize them and we can take advantage of them. But if you go to the URL movie/{movie-name}/photos
, still you'll see that your single-movie.php or single.php templates are taking care of these URLs. If you see 404 error for our custom URL, don't worry, just save your permalinks again.
3. Set the Template
function prefix_url_rewrite_templates() { if ( get_query_var( 'photos' ) && is_singular( 'movie' ) ) { add_filter( 'template_include', function() { return get_template_directory() . '/single-movie-image.php'; }); } if ( get_query_var( 'videos' ) && is_singular( 'movie' ) ) { add_filter( 'template_include', function() { return get_template_directory() . '/single-movie-video.php'; }); } } add_action( 'template_redirect', 'prefix_url_rewrite_templates' );
Here we are saying that, if there is a query var photos
or videos
and it's a single movie
page, we are setting the template as single-movie-image.php and single-movie-video.php respectively.
So, single-movie-image.php
is responsible for movie/{movie-name}/photos
query and single-movie-video.php
is responsible for movie/{movie-name}/videos
query. Simple eh?
Comments