Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

Custom Page Template Page Based on URL Rewrite

by
Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

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:

  1. Add a rewrite rule on a custom post type permalink
  2. 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?

Note: In the section of setting the page template, we are using PHP anonymous functions. So, this code will need minimum PHP 5.3.0 support or you could use the filters the old way. One thing to remember with using anonymous functions is that, you can't unregister a filter or action as you could do normally. But it's an easy way to bind an action/filter without giving the function a name.
Advertisement