I'm trying to use this page_template template from the WP forums, with the same aim as the original author:

I am trying to use two separate permalinks/templates for a single post - each providing different views of the post (through different templates). http://example.com/category/post-name -> uses template1.php http://example.com/category/post-name/details -> uses template2.php

I've modified the code according to the changes discussed in the thread, but my alternative template (for a custom post type) isn't being loaded — /post-name/detail just redirects to /post-name/.

Any ideas?

// Add 'detail' to the permalink structure / query string 
function detail_rewrite_rules( $rules ) {
    $newrules = array();
    $newrules['(.+?)/([^/]+)(/[0-9]+)?/detail/?$'] = 'index.php?category_name=$matches[1]&name=$matches[2]&page=$matches[3]&detail=1'; 

    return $newrules + $rules;
add_filter( 'rewrite_rules_array','detail_rewrite_rules' );

function detail_flush_rules(){
    $rules = get_option( 'rewrite_rules' );

    if ( ! isset( $rules['(.+?)/([^/]+)(/[0-9]+)?/detail/?$'] )   ) {

        global $wp_rewrite;
add_action( 'init','detail_flush_rules' );

// Open up 'detail'
function detail_queryvars( $qvars ) {
  $qvars[] = 'detail';
  return $qvars;
add_filter('query_vars', 'detail_queryvars' );

// Switch between templates
function filter_single_template($template){

    $object = get_queried_object();
    $templates = array();

    /* If detail is in the query string, create a list of templates to use */
    // if($_GET['detail']) {
    // if( get_query_var('detail') ) {
    global $wp_query;
    if ( $wp_query->query_vars['detail'] ) {    
        echo "<script>console.log('Detail template activated');</script>";
        $templates[] = "single-photos-detail.php";
        // $templates[] = "detail-single.php";
        // $templates[] = "detail-single-{$object->post_type}.php";

    /* If one of our custom detail templates exists, return it.
     * Otherwise return the original template
    $templateSwitch = locate_template($templates);
    return (!empty($templateSwitch)) ? locate_template($templates) : $template;
add_filter('page_template', 'filter_single_template');

1 Answer 1


WordPress has a simpler function for what you're trying to do, add_rewrite_endpoint. Additionally, the filter for a single post template is single_template, page_template fires on the page post type.

function wpd_detail_endpoint(){
    add_rewrite_endpoint( 'detail', EP_PERMALINK );
add_action( 'init', 'wpd_detail_endpoint' );

function wpd_detail_template( $template = '' ) {
    global $wp_query;
    if( ! array_key_exists( 'detail', $wp_query->query_vars ) ) return $template;

    $template = locate_template( 'single-photos-detail.php' );
    return $template;
add_filter( 'single_template', 'wpd_detail_template' );

This assumes the template exists, you may want to do some additional checks as you've got in your original function.

  • Thanks Milo. I used a plugin-ized version of this as described at gist.github.com/joncave/2891111 — without doing this I couldn't get the permalink rewrite to happen. Commented Mar 15, 2014 at 9:07
  • Sorry, I left out flushing rewrite rules. You can also do that manually by visiting the permalink settings page.
    – Milo
    Commented Mar 15, 2014 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.