0

I use following code (Source) to change the single post template via url parameter:

function sjc_add_query_vars($vars) {
return array('template') + $vars;
}
add_filter('query_vars', 'sjc_add_query_vars');

function sjc_template($template) {
global $wp;
if ($wp->query_vars['template']=='basic') {
return dirname( __FILE__ ) . '/single-basic.php';
}
else {
return $template;
}
}
add_filter('single_template', 'sjc_template');

The Code above works fine, so for example:

........com/my-question/

changes the template by calling:

........com/my-question/?template=single-basic/

Question:

How can i rewrite the URL to remove the "?template=" part to get clean URLs like

........com/my-question/single-basic/

Note:

A solution for this problem would be awesome - because i also realized that my Caching Plugin "CACHIFY" unfortunately do not cache the posts with the "?template=" part in the url :(

1

Your should add rewrite endpoint template on theme activation hook and init hook. Also there is some little checks to perform to prevent errors.

function sjc_theme_activate(){
    sjc_theme_add_rewrite_endpoint();
    flush_rewrite_rules();
}
//for more info http://codex.wordpress.org/Plugin_API/Action_Reference/after_switch_theme
add_action( 'after_switch_theme', 'sjc_theme_activate' );


function sjc_theme_deactivate(){
    flush_rewrite_rules();
}
//for more info http://codex.wordpress.org/Plugin_API/Action_Reference/switch_theme
add_action( 'switch_theme', 'sjc_theme_deactivate' );

function sjc_add_query_vars($vars) {
    $vars[] = 'template';
    return $vars;
}
add_filter('query_vars', 'sjc_add_query_vars');

function sjc_template($template) {
    global $wp_query;
    //you should check if file exists first
    if ( (isset($wp_query->query_vars['template'])) && ($wp_query->query_vars['template'] == 'basic') && (file_exists(dirname( __FILE__ ) . '/single-basic.php')) ) {
        return dirname( __FILE__ ) . '/single-basic.php';
    }else {
        return $template;
    }
}
add_filter('single_template', 'sjc_template');

//add rewrite endpoint
function sjc_theme_add_rewrite_endpoint(){
     add_rewrite_endpoint( 'template', EP_PERMALINK | EP_PAGES );
}
//for more info http://codex.wordpress.org/Rewrite_API/add_rewrite_endpoint
add_action('init', 'sjc_theme_add_rewrite_endpoint');

then Activate pretty links for wordpress. You can visit any post with
http://example.com/post-title/?template=basic
http://example.com/post-title/template/basic
And get the same result (don't forget to add single-basic.php file in theme base dir). I hope this will help you.

  • Hi! That rocks!!! WORKS perfect. Thank you so much! Quick Question to the "flush_rewrite_rules();" the codex mentioned something like "this is an expensive operation"... Does it only executes during theme activation or on every page load? – NewUser Nov 23 '14 at 19:19
  • It must be executed only at theme activation, plugin activation and plugin deactivation and only if plugin and/or theme create new rewrite rule. it simply update rewrite rules of your wordpress install.it will be bad practice if you execute function at each request. in previous code it run only during theme activation. – Ahmed Nov 23 '14 at 20:12
  • Thank you so much for the clarification. Im so happy to solve my last big problem with your help. You rock! – NewUser Nov 24 '14 at 4:10
  • Hi again - there is a Problem. The post categories doesnt work anymore! I got a 404 error... Any idea. I removed your code, flushed the permalinks and it worked again. When i use the code it brokes my category links? – NewUser Nov 24 '14 at 5:04
  • I thought that after_setup_theme run only on activation but i was wrong. after searching i found that after_switch_theme and switch_theme run only after theme activated and deactivated and that's exactly what will solve the issue. i updated code in this post. Sorry man, I don't play with themes. – Ahmed Nov 24 '14 at 14:57
0

You can also rewrite URL using htaccess, it can also redirect to a pretty URL. Just put this code into your .htaccess file.

RewriteEngine On
RewriteRule ^my-question/([^/]*)$ /my-question/?template=$1 [L]

Or

You can also done it with functions.php using following code snippet.

global $wp_rewrite;
add_rewrite_rule('^my-question/([^/]*)?$', '/my-question/single-basic.php?template=$matches[1]', 'top');
$wp_rewrite->flush_rules();
  • Hi! Thx for the answer - any way to put a rewrite like this into the functions.php? Would be awesome – NewUser Nov 23 '14 at 6:11
  • Yeah NewUser i updated my answer for your requirement. – Nik Lakhani Nov 24 '14 at 7:49
  • thx - how can i change the "my-question" part to all? I mean it should rewrite alle posts? The my-question part is the post title and it is individual because i have more than one post ;) – NewUser Nov 24 '14 at 7:53
  • You need to write separate rewrite rule for each post type. i am also using this code for my website css-diary.com – Nik Lakhani Nov 24 '14 at 8:30
0

Update: I've come to realize that we have different goals... @NewUser accepts that both URL styles work:

http://example.com/post-title/?template=basic

and

http://example.com/post-title/template/basic.

While my goal is to never see http://example.com/post-title/?template=basic, by having it redirect to a pretty URL. Just like domain.com/?p=100 redirects to a pretty post/page URL. WP itself does this via a wp_redirect function in canonical.php.

Please note: Having different URL styles (pretty and non-pretty) serve the same content, might be seen as duplicate content by search engines. Use a 301 redirect function (as described below) or canonical tags to prevent this: https://support.google.com/webmasters/answer/139066?hl=en This also explains the whole purpose of WP's canonical.php (preventing dupes).

Non-pretty to Pretty URL / 301 redirect function: I modified the following function. It now redirects to the pretty URL and prevents duplicate content caused by having different URL styles (pretty and non-pretty) serve the same content:

function redirect_to_pretty_url() {
    if ( is_singular() && !empty( $_GET['template'] ) ) {
        wp_redirect( home_url( "/my-question/" ) . urlencode( get_query_var( 'template' ) ), 301 );
        exit();
    }   
}
add_action( 'template_redirect', 'redirect_to_pretty_url' );
  • Hi! Thx for the answer - a redirect like this is in my opinion the last option. – NewUser Nov 23 '14 at 6:12
  • @NewUser: Please see my updated answer. I thought we were looking to solve the same problem, but I've come to realize that that doesn't seem to be the case here. I hope my updated answer explains everything. – Ralph Nov 24 '14 at 23:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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