One Permalink Only

Thanks to Matt, I found this cool WordPress plugin by Scott Yang that aims to unify your site’s permalinks. Say you have an entry at and people link to (without a trailing slash). That will get indexed by search engines as two different entries, and may even hurt your ranking. The Permalink Redirect Plugin fixes that by sending a 301 redirect to such requests. Very cool.

I have something that will take that one step further. This code will turn into and the second part will enforce your use or non-use of www.

Here it is as a plugin: Enforce www. Preference

And here is the code, in case you just want to integrate it into something else. This could very well go at the bottom of Scott’s plugin, or within the function.

if ( $_SERVER['REQUEST_URI'] == str_replace('http://' . $_SERVER['HTTP_HOST'], '', get_bloginfo('home')) . '/index.php' ) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: ' . get_bloginfo('home') . '/');
if ( strpos($_SERVER['HTTP_HOST'], 'www.') === 0  && strpos(get_bloginfo('home'), 'http://www.') === false ) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://' . substr($_SERVER['HTTP_HOST'], 4) . $_SERVER['REQUEST_URI']);
} elseif ( strpos($_SERVER['HTTP_HOST'], 'www.') !== 0 && strpos(get_bloginfo('home'), 'http://www.') === 0 ) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://www.' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);


  1. says

    Then they can comment that part out. ;-) Or, they can switch it around to insert it if it’s not there, fairly easily, although it should really be done at the Apache level. The point is to standardize it one way or another.

    This should work:


    Okay, that got butchered horribly, I’ll add it to the phps commented out.

  2. says

    Even better, I added auto detection. It will consider what you have set as your blog’s URI in WordPress and enforce yes-www or no-www accordingly. Everybody wins!

  3. says

    Like I stated earlier, the trailingslashed vs. untrailingslashed IRI thing is just one example. Stuff like would also be redirected to the correct permalink IRI.

    As for your plugin, great work. Both www. and index.php are indeed cruft. However, I prefer to do these things through some mod_rewrite rules. (I guess stuff like this could also be made as a WP plugin…)

  4. says

    How about removing all instances of index.php in IRIs?

    if(strstr($req_uri, '/index.php')) {
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . get_bloginfo('home') . str_replace('/index.php', '/', $req_uri));

    Also, try to use single quotes where possible when coding in PHP. They’re a couple of milliseconds faster.

  5. says

    Mathias, yeah, I do the no-www thing using mod_rewrite as well, but for people who aren’t comfortable tinkering with .htaccess this is a simple plug-and-play way to do it. mod_rewrite would be faster.

    As for removing all instances of index.php, that’ll break some blogs. For instance, people who have permalinks like /index.php/2005/04/03/title-of-post/ that use PATHINFO would be in trouble, and all pages except for the front page would 404.

    Of course, we could remove /index.php? and replace it with /? for people who aren’t using mod_rewrite rules, but I think Scott’s plugin already does that.

    As for doublequotes vs singlequotes… I usually try to use single. I just copy pasted that header("Location: " part from something else! I’ll fix that.

  6. says

    Good point. I suppose you could do something like this, then:

    if(!strstr(get_settings('permalink_structure'), '/index.php') && strstr($req_uri, '/index.php')) {
    header('HTTP/1.1 301 Moved Permanently');
    header('Location: ' . get_bloginfo('home') . str_replace('/index.php', '/', $req_uri));


  1. in general cases. WordPress users, though, are afforded an additional line of defense against the accursed Triple Dub via several useful plugins. After some careful searching, I recently deployed Scott Yang’s Permalink Redirect and Mark Jaquith’s Kill http://www., Kill index.php plugins. The combination of the two has given me exactly what I was looking for. By default, WordPress uses some .htaccess trickery to create user-friendly URLs for entries, archives, pages, etc., so that instead of seeing

  2. [...] Speaking of permalinks, though I was steered over to only the best plugin ever. Well, actually two plugins, but basically they’re rather much the same idea. I always wondered what the importance of that trailing slash was and now I know — so anyway I’ve implemented both over at the webby and it’s a wonderous thing. (Which really will launch soon, I promise!) [...]

  3. [...] The other day I was on the WP forums and in answering some issues over there, I was steered over to to this post/plugin. Actually it’s two separate plugins, but essentially they’re doing the same kind of thing – redirecting links to the right place. If you’re using "pretty" permalinks, I strongly advise downloading at least the permalink redirect plugin. Scott explains it rather well, but in essence there’s a flaw in the coding of permalinks that basically create two links to the same post (three if you count the old ID method – p=359720398). The plugin takes all of those factors into consideration and 301 redirects every link to the proper permalink. (I’ve heard that this will be making it into the core at some point.) The other plugin mentioned in the post is enforce www preference. I used to use htaccess to accomplish this, but now I’m glad of either way because apparently there’s a small cookie issue if you use password protected posts and you enter the password at a link not the one your blog URL is. (i.e. if your URL doesn’t have a www and you go to the password protected page via the www link, it won’t do anything when inputting a password). Anyhow, thought I’d share this find with the other WPers here. Cheers! ____________________________________________ Webby: (on Pass36) Blog: "For that which I love, for that which gives me love, I will do what I can." [...]

  4. [...] [wp-hackers] WordPress 2 [wp-hackers] WordPress 2 Denis de Bernardy denis at Tue Dec 20 23:17:32 GMT 2005 Previous message: [wp-hackers] WordPress 2 Next message: [wp-hackers] WordPress 2 Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] > > Some bugs are fun, e.g. when you add a child to ‘a page with a very > > very very long page title’. > > Elaborate. try it. it’s missing some css to make the select box fixed width + likely the options right aligned. > > Others are just annoying, e.g. TinyMCE randomly adds spaces in FF. > > Hmmm, I don’t notice random spaces. I’ll play with it. unless I am mistaking a similar bug is in trac already (IE extra spaces regex). I reproduced by entering several empty paragraphs in a row in FF on a Windows box > > Others are merely uncaught cases, e.g. the implode error in > the file > > list when no .htaccess file exists. > > Error message? file(c:Inetpubwwwrootsemiologic2/) [function.file]: failed to open stream: Permission denied in c:Inetpubwwwrootsemiologic2wp-adminadmin-functions.php on line 1447 with var_dump($file) returning string(0) "" > If it’s not editable, the suggested structures should have > index.php/ prepended so that PATH_INFO is used instead of > .htaccess. If you use a custom structure, you’re own your own. Several sites recommend /%post_id%/%postname% as the more ideal SEO permalink structure. Those who set this up without any idea of what they’re doing will end up asking for help in the forum if no warning is raised. > The theme will be reset if you visit the Presentation page. Correct, but take my word for it as I’ve handled such an event a dozen times when I removed the login link in the last release of my theme: Until then, the user is crying for help because he lost his link to the admin area. > $wp_rewrite is not available until just before the ‘init’ action. yep thanks… I eventually pinned the problem by hooking the relevant plugin calls into the init action. still, it might make sense to force the instantiation in the event someone tries to use it before it is available. my guess is some of the other wp classes are not available in the shutdown hook either (cf the bug I filed), since not instantiated as references. As an aside, does anyone know which of these plugins are no longer useful in WP2? Check IP Behind Proxy Cookie Timeout (@Michael, if on list: send an email for the fix/update) Paged Comment Editing Enhanced Post List FixBack: Impostercide Kill/Keep http://www., Kill /index.php Smart Update Pinger Twilight AutoSave WP-Cron Future Pings Permalink Redirect D. Previous message: [wp-hackers] WordPress 2 Next message: [wp-hackers] WordPress 2 Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] More information about the wp-hackers mailing list [...]

  5. .htacess file to redirect to as WWW is deprectiated. I have been using just for some time now as my preferred URL. Of course, I could have used this plugin instead of hacking my .htacess file. A word of caution Cool URIs don’t change. In order to answer this question, we must first recall the definition of WWW: World Wide Web: n. Abbr. WWW 1) The complete set of documents residing on all Internet