Clean URLs for custom $_GET variables

I have a query var show=othertemplate that I can add to any URL to show any post, page or archive in WordPress in a different template, like this: mysite.com/[any URL]/?show=othertemplate. I’d like for it to be accessible via clean URL, like [any URL]/othertemplate or [any URL]/show/othertemplate.

I have tried achieving this by registering the query var with a query_vars filter and adding code like below to .htaccess, but WordPress intervene and throws a 404. WP Debug Bar says that the query is looking for attachment=print.

Read More
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/index.php
RewriteRule ^(.*)/othertemplate/?$ /index.php/$1?view=othertemplate [L]

I have also tried using the WordPress rewrite functions, but the same thing happens.

function st_myqueryvars($vars) {
    $vars[] = 'show';
    return $vars;
}

add_filter('query_vars', 'st_myqueryvars');

function st_myrewriterules( $wp_rewrite ) {
  $newrules = array();
  $new_rules['^(.*)/othertemplate/?$'] = 'index.php/$matches[1]?show=othertemplate';
  $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_filter('generate_rewrite_rules','st_myrewriterules');

Is there something I’m missing here?

Update: After flushing permalinks I see that this WP function rewrites /[any URL]/template to index.php?show=template instead of
index.php?[the URL’s corresponding query string]&show=template. I
can’t ‘hard code’ a query string like
post_type=$matches[1]&name=$matches[2]… into the rewrite rule
because it needs to work for any page/post/archive, which have different permalink structures. How do I get around this?

Related posts

Leave a Reply

2 comments

  1. You should look at “Rewrite Endpoints”, which are much simpler to work with than custom rewrites. And they fit your use case perfectly: http://codex.wordpress.org/Rewrite_API/add_rewrite_endpoint

    You might add your “show” endpoint like so:

    function wpsx_37961_add_endpoints() {
    
        // Add the "show" rewrite endpoint to all URLs
        add_rewrite_endpoint('show', EP_ALL);
    
    }
    add_action('init','wpsx_37961_add_endpoints');
    

    Then you can check for its value on the WP action (or maybe earlier, I’m not sure), like:

    function wpsx_37961_check_endpoint() {
    
        $show = $wp_query->get( 'show' );
    
        // Now, do whatever template switching you want based on the $show var's value
    
    }
    add_action('wp','wpsx_37961_check_endpoint');
    

    The work of actually switching templates is up to you, but this gets your endpoints in place. No filtering query vars, no hacking together rewrite rules, no tough stuff 🙂

  2. Check out my post here. This should help you along your way. You’re on the right track. Once you add a rewrite rule, remember to flush the perms by visiting Settings->Permalinks