Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Is there any way to add the .html extension to custom post types without plugin ?

For posts I can use /%postname.html on the permalink settings

For pages I can use:

add_action('init', 'change_page_permalink', -1);
function change_page_permalink() {
    global $wp_rewrite;
    if ( strstr($wp_rewrite->get_page_permastruct(), '.html') != '.html' ) 
        $wp_rewrite->page_structure = $wp_rewrite->page_structure . '.html';
}

For Custom post types ???

Is there any piece of code similar to the one above that allws me to change or to add the .html on the custom post type url ?

share|improve this question
5  
Just wondering for what reason you want to add .html? –  Vince Pettit Jul 19 '12 at 15:29
    
Well, function post-type_permalink will throw an error. If you don't receive this error, then you've got something painfully wrong with your debug settings. Also please rework your question with the correct intends on the lines. Thanks. –  kaiser Jul 25 '12 at 15:11
    
@kaiser, Is just to know how can I use the same permalink settings on the custom post types. If I set /$postname.html for the posts, how can I use the same for the custom post types. –  user983248 Jul 25 '12 at 15:21
    
You didn't read a single line I wrote in my comment, right? Please fix your code. Also - doesn't work in function names... –  kaiser Jul 25 '12 at 15:23
    
@kaiser Yes I did, but I'm not Flash, and I have a hand problem, so I can't type as I think or speak –  user983248 Jul 25 '12 at 15:29

3 Answers 3

up vote 5 down vote accepted
+25

This seem to work:

Create the rewrite rules like post-type/post-name.html. You can use arrays to create the rules for just some set of post types instead of doing it for all of them.

add_action( 'rewrite_rules_array', 'rewrite_rules' );
function rewrite_rules( $rules ) {
    $new_rules = array();
    foreach ( get_post_types() as $t )
        $new_rules[ $t . '/([^/]+)\.html$' ] = 'index.php?post_type=' . $t . '&name=$matches[1]';
    return $new_rules + $rules;
}

Format the new permalink structure for these post types.

add_filter( 'post_type_link', 'custom_post_permalink' ); // for cpt post_type_link (rather than post_link)
function custom_post_permalink ( $post_link ) {
    global $post;
    $type = get_post_type( $post->ID );
    return home_url( $type . '/' . $post->post_name . '.html' );
}

And then stop redirecting the canonical URLs to remove the trailing slash. This might need some more work, as you'll probably want to keep the redirection for most cases.

add_filter( 'redirect_canonical', '__return_false' );

As others said around here, after doing the above you'll need to flush the rules, and that's possible by visiting the options-permalink.php admin page in Dashboard -> Settings -> Permalinks.

share|improve this answer
6  
Oi Vinicius, a good answering practice is to prefix all function names with wpse_59024_ (Question ID) to avoid conflicts of copy/pasta ;) . . . And has the extra benefit of knowing which Answer does that code belongs in our snippets library. . . . . +1 Spot on! –  brasofilo Jul 28 '12 at 13:13

You could add a rewrite rule for this that supersedes the built-in permalinks, e.g. for a custom post type "product"...

add_action('init', 'add_html_ext_to_custom_post_types');
function add_html_ext_to_custom_post_types() {
    add_rewrite_rule('^product/([^/]+)\.html', 'index.php?product=$matches[1]', 'top');
}

(Don't forget to flush your rules either by re-saving your permalinks or using flush_rules in the way @toscho notes above).

Caveats

  • I don't think functions like the_permalink() would use this, so you might have to add a filter for post_link to catch those links. You could also add to the redirect_canonical filter to redirect the default permalinks, so that /product/foo and /product/foo/ redirect to /product/foo.html.
  • You would need to add addition rewrites for other URLs that your site used, like feed URLs, subsequent pages, trackbacks, etc. The code above would just work for the main Custom Post Type page.
share|improve this answer

If you would prefer a WordPress plugin to handle the work for you, check out Custom Post Type Permalinks in the WordPress plugin repository. Tested on WordPress 3.4.1 and it works perfectly.

After activating the plugin, just navigate to Dashboard -> Settings -> Permalinks. You can add specific rewrites for each registered custom post type.

share|improve this answer
3  
Do not flush the rewrite rules on every page load. –  toscho Jul 19 '12 at 14:07
    
that code is not working, also if you just copy and paste code from xplus3.net/2010/05/20/wp3-custom-post-type-permalinks make sure that it works as expected -1 for not testing –  user983248 Jul 19 '12 at 14:11
    
@toscho how do you suppose to do that or to stop that ? –  user983248 Jul 19 '12 at 14:15
1  
flush_rules() should be called on de/activation only because it is very slow. You can check $GLOBALS['wp_rewrite']->rules to see if the rules are known already. –  toscho Jul 19 '12 at 14:19
    
@Michael Ecklund It gives a 404 I does not work. Did you test that code ? –  user983248 Jul 19 '12 at 14:20

protected by Community Mar 17 '13 at 0:41

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

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