Monday, February 5, 2007

Converting from Movable Type to WordPress permalinks

Well, it’s almost a year late. When I converted from Movable Type to WordPress, one of the things I put off doing was switch to WordPress permalinks for individual posts. I know, this sounds like a completely useless discussion – whether your posts are published at or couldn’t be more boring, right?


Turns out, it’s much better to use hyphens in your permalinks. (If you care about how your site ranks in Google and you’re not reading Matt Cutts, you don’t care about how your site ranks in Google.) So… I could abandon 5 years of archives at old URLs (definitely not preferable), or I could use htaccess to convert underscores to hyphens. Only problem is, I can’t for the life of me understand htaccess and its voodoo ways. So I punted, and installed the Underscore Permalinks plugin and just published in WordPress to the same URLs I’d published in Movable Type.

Then a funny thing happened. I started speaking at Search Engine Strategies conferences, and I’d often co-present with Stephan Spencer, one of the founders of Netconcepts. Stephen knows a lot about SEO for blogs, and was adamant that using hyphens was the only acceptable option when it came to permalinks. Whenever I’d tinker with my blog, I’d make a note that I should really figure out how to convert the underscores to hyphens. Each time I looked, it seemed hard. And hard = not tonight.

Last week, I dropped Stephan a note. The first step to solving a problem, I reasoned, was admitting I had one. Sure enough, Stephan not only came back with some useful advice, he actually looked into the specifics and figured out some helpful info:

  • the Underscore Permalinks plugin actually modifies the post_name row in the wp_posts table by swapping the hyphens out with underscores. I’d need to modify the post_name entries for all 2500 posts to replace the underscores with hyphens. (For those who are curious, the SQL command to do this is:
    update wp_posts set post_name = replace(post_name,'_','-');

  • I’d need to deactivate the Underscore Permalinks plugin so that future posts won’t be modified.

  • I’d need to implement a script in htaccess to search for underscores and replace them with hyphens.

The first two steps were pretty straightforward, though I’m pretty sure I wouldn’t have figured out the first without Stephan’s help. With those accomplished, I set out to implement the htaccess rules Stephan sent me. (Talk about above and beyond the call of duty, Stephan actually bothered to write up the 10 lines of code necessary to do the transformation!)

This is where I hit a bit of a roadblock. No matter how I tweaked the htaccess rules, I couldn’t get it to do the right thing. While IMing with Ed, I mentioned my headache, and he quickly hit Google and found this page, which seemed to document precisely what I was trying to accomplish. (Of course, the author hadn’t postponed his misery by a year, so he didn’t have to deal with my database and plugin issues. Lucky for him!)

With a little massaging, I was able to implement the author’s solution of creating a simple PHP file (convertperma.php) and referencing it in the htaccess rules; now, requests for the old permalinks do the right thing. (One caveat: I can’t figure out how to make the rewrite rule in ColdForged’s instructions be a 301 redirect; I’ll worry about that after I get some sleep!) I’ve also regenerated my Google Sitemap (using the excellent Google Sitemap plugin), which should help in getting the right permalinks indexed by Google. And adding the Landing Sites plugin code to my 404 page means that any errant search results that bring up a 404 will at least include helpful pointers to pages that are related to the originating query.

It’s not perfect, I’ve found a couple pages that appear to be edge cases that will need further attention. But this is more than 99% of the way to completion; I couldn’t have done it without Stephan’s and Ed’s help. Thanks, guys. I owe you both big time!


  1. That makes me feel better ;)

    The site looks great, but I sympathize with the switch challenges. Not having anywhere near your expertise, I fumbled through it and I'm much, much happier on WordPress.

  2. Rick,

    $status = "HTTP/1.x 301 Moved Permanently";
    header("Location: $request");

  3. Will - I just throw that in the existing convertperma.php script?

  4. Yep. Just put the first two lines above the header() line already there.

  5. I had a similar issue on my blog and used a perl script to solve it. You might also be able to repurpose the php from a Blogger->Wordpress tutorial I wrote. Let me know if you have any lingering issues... Will's "status" http header should get you 301's.

  6. Stephan Spencer's knowledge and helpfulness with Wordpress is nothing short of amazing. Of well over a dozen experts - he was the only one that could isolate my trackback problem that I was having.

  7. We have a similar problem with switching from b2evolution. None of our old permalinks (from search engines or other blogs) work b/c of the dash/underscore thing. B2 truncates slugs and uses underscores for apostrophes as well as spaces. Our redirect plugin can't account for that, so we're having to go change all 3500 posts to the b2 slug manually as I haven't found a tool to do it for us. IF anyone has a better idea of how to fix those broken links, we're all ears!