Custom Page Template Page Based on URL Rewrite

Custom Page Template Page Based on URL Rewrite

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.
Tareq Hasan is wedevs on Codecanyon
Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • harishchouhan

    Great article. Short and to the point without missing any details.

  • http://www.facebook.com/dmshevch Дмитрий Шевченко

    add_filter( ‘template_include’, function( $path ) {
    if ( get_query_var( ‘photos’ ) && is_singular( ‘movie’ ) ) {
    return get_template_directory() . ‘/single-movie-image.php’;
    }
    if ( get_query_var( ‘videos’ ) && is_singular( ‘movie’ ) ) {
    return get_template_directory() . ‘/single-movie-video.php’;
    }
    return $path;
    });

    IMHO this is simpler way for step 3.

    • chodorowicz

      Perfect for PHP 5.3 and up.

  • Pingback: WordPress news: March 17 to March 23, 2013

  • Pingback: Tweet Parade (no.12 Mar 2013) | gonzoblog

  • argron

    thanks for this short and straight to the point tutorial, however it’s not adding the rewrite rules to the .htaccess file so it doesn’t work!!!

    i believe I’m missing something regarding add_rewrite_rule()…

  • http://www.facebook.com/rashid.shafique Rashid Shafique

    not working

    • http://www.facebook.com/rashid.shafique Rashid Shafique

      my bad, missed the custom post type part! thx

  • Pingback: WordPress news: March 17 to March 23, 2013 | Uber Patrol - The Definitive Cool Guide