Like relationship break-ups, leaving a blog engine (for another, no less!) is not easy. There’s pleading (”Stick with Blogger, it’ll change to meet your needs, I swear!”), denial (”Database driven blogs are slower than statically published blogs.”), and crying (”Why, why, oh why is this so hard? *sob*”). Not to mention the “grass is greener” syndrome: “only once I switch to Wordpress will I truly be happy - it will have every single feature I need!”.
That’s been my spare-time-life on and off over the past few weeks, and now you all get to benefit from my pain. Here are the requirements I had to move to a new blogging platform:
- Self hosted - while not a hard-and-fast requirement, I really want something I can tweak if necessary. And it can’t be ASP.NET-based, as much as I wanted it to, because I’m not going to pay for ASP.NET hosting. As a developer I also get warm fuzzies about being in 100% absolute control. (Okay, really, as a human being I get warm fuzzies about being in 100% absolute control…)
- Old permalinks need to 301 redirect to new permalinks - I don’t have a lot of subscribers (but I love you all, so very much) and get a very modest number of hits every day. I really want/need those old links to point to the new ones. It needed to be seamless.
- Full, or nearly-full, import - I wanted to bring as much information as possible from my Blogger blog to my new blog platform. That means no “import from RSS” features for me, I wanted comments to come over, etc.
- Well used/tested, and feature rich - I wanted a blog engine that’s been proven. I don’t want to be overwhelmed with spam, or anything else. Along those lines, if a platform is going to be mature, it should have plenty of features. I want to be able to do things like moderate comments (if I ever feel like it), write an occasional article instead of a blog post, etc.
Given those requirements, I decided to switch to Wordpress, and here’s how I did it. (Spoiler: it took longer than I thought it would, required some custom development, and worked out okay in the end.)
I would divide my tasks into three components: exporting from Blogger, importing to Wordpress, and “general configuration” (permalink redirects, etc.)
Export from Blogger
I’ve actually already posted on this here. I decided on BlogML as my “offline” format for my blog, and wrote a PowerShell script to export from Blogger and output the BlogML format. So step one, export to BlogML using my script.
![]()
Figure 1. Exporting from Blogger to a local BlogML file.
Import to Wordpress
Update: Rob Walling from softwarebyrob.com has updated the import module to work with Wordpress 2.3 - get the updated version from my tools page. Thanks Rob!
This took the most work. The first thing I had to do was write a Wordpress import module for BlogML, since none existed. You can download the import module here. IMPORTANT NOTE: This requires the Php.XPath library available from SourceForge. Go there and download v3.5, making sure to upload it to the same directory as “blogml.php” (typically something like “/wp-admin/import/”). It is a single .php file. You’ll need to do this at least until I figure out how licensing works between BlogML and Php.XPath–once I get that figured out I’ll be adding this import module to the BlogML CodePlex project.
My steps were as follows:
- Back up my Blogger files (on my FTP server) to my local hard drive.
- Log into my Wordpress install and update the URL to be “http://www.aaronlerch.com/blog” (instead of the intermediate location of “http://www.aaronlerch.com/wp”). Note that as soon as I saved this setting, it tried to redirect me to a location that doesn’t exist yet. It’ll fail, that’s okay.
- Rename the “/blog” directory with my Blogger files to something else, and rename my intermediate Wordpress directory “/wp” to “/blog”.
- Change the encoding in my BlogML output file. This sucks, but the XML class I used (Php.XPath) requires the XML to be in UTF-8 format. My Blogger->BlogML export script generates it using the .NET APIs, which uses UTF-16 (Unicode) encoding by default. Instead of spending a lot of time tweaking the BlogML output-which wouldn’t benefit anybody but myself-I just fired up Notepad2 and changed the file encoding to UTF-8 (File -> Encoding -> UTF-8), making sure to also update the “encoding” attribute of the “<?xml” header tag from “utf-16″ to “utf-8″.
![CropperCapture[1]](http://www.aaronlerch.com/files/blog/BreakingUpMovingBlogEngines_B582/CropperCapture1.png)
Figure 1. Be sure to change the “encoding” attribute of your XML file when changing the file encoding.
![CropperCapture[2]](http://www.aaronlerch.com/files/blog/BreakingUpMovingBlogEngines_B582/CropperCapture2.png)
Figure 2. Before conversion - “Unicode BOM” (BOM = Byte Order Mark)
![CropperCapture[3]](http://www.aaronlerch.com/files/blog/BreakingUpMovingBlogEngines_B582/CropperCapture3.png)
Figure 3. After conversion - “UTF-8″ - Import my BlogML export from Blogger into Wordpress (very straightforward–just try it). On the “completed” page of the import, it lists the posts that were imported, and at the bottom it gives a link to a permalinkmap.csv file which contains a mapping of old permalinks to new permalinks. I downloaded that file and saved it for use later.
General Configuration
Finally, I needed to set up my redirects. Using the permalinkmap.csv file I downloaded, I ran the following PowerShell one-liner to create a text file containing entries that I copied into my “.htaccess” file (my hosting company uses LAMP):
import-csv permalinkmap.csv |% { $oldurl = ($_.OldPermalink -replace “http://www.aaronlerch.com”, “”); “redirect 301 $oldurl ” + $_.NewPermalink } | out-file htaccessredirectdata.txt
It simply creates a list of redirect commands that end up looking something like this:
redirect 301 /blog/2007/08/uri.html http://www.aaronlerch.com/blog/2007/08/21/uri-purity/
Finally, I needed to set up redirects for my archive files. Those were all stored in a single “archive” subfolder by Blogger, which I had locally as part of my original backup. This PowerShell one-liner output more redirect commands for me to copy into my .htaccess file:
dir archive | select Name |% { ($_ -match “([0-9]{4})_([0-9]{2})_.*”) | out-null; “redirect 301 /blog/archive/” + $_.Name + ” http://www.aaronlerch.com/blog/” + $matches[1] + “/” + $matches[2] + “/” } | out-file archivehtaccessdata.txt
This short command takes a file named “2007_08_01_archive.html” and produces the following redirect line:
redirect 301 /blog/archive/2007_08_01_archive.html http://www.aaronlerch.com/blog/2007/08/
Cleanup
What good blog migration would be complete with out some cleanup? The export/import process mangled some special characters various blog writing tools I’ve used inserted. Not to mention code examples getting new-lines removed. (Beware!) A quick visual skim and it was all fixed up.
Conclusion
So what do we take away from all this? A few things:
- Cleanly migrating between blogging platforms sucks. It’s not straightforward, and “clean” is in the eye of the beholder.
- If you ever want to migrate from Blogger to Wordpress, you’ve hopefully found some help here. At a higher (even more helpful) level, if you ever want to export from Blogger to BlogML, or import from BlogML to Wordpress, you’ve got some tools and guidance.
Technorati Tags: blogml, blogger, wordpress, powershell


August 24, 2007 at 15:55
Nice job, Lerch. And nice theme too. I love the fluid sizing option.
August 24, 2007 at 16:00
By the way, instead of 301 redirection if you have access to the head tag in your blog you could use <meta http-equiv=”refresh” content=”0″ url=”your site”>. That would just send you to the new page once the old page loaded.
August 24, 2007 at 16:14
True, but then:
a) the old page still has to load in entirety before the new page will load,
b) it’s not permanent — I want to permanently redirect since the old pages don’t even exist anymore, and
c) search engines won’t recognize that as a valid redirect
Here’s a decent summary of redirect techniques:
http://www.theinternetdigest.net/archive/301-redirects-seo.html
And here’s another:
http://www.bruceclay.com/blog/archives/2007/03/how_to_properly.html
August 24, 2007 at 16:49
True, but not everyone can get to their htaccess file too. I’m just suggesting another option.
August 26, 2007 at 04:37
Hi
Unfortunately I can’t download the import module for wordpress. Could you send it to me in an email or fix the download link?
August 26, 2007 at 08:17
Whoops–that’s what I get for making some assumptions (and not testing them).
It’s available as a .zip download now, sorry about that! The link has been fixed.
November 7, 2007 at 10:46
How about the other way? Exporting BlogML from Wordpress?
Does anyone know if this has been done? I’ll get started on it if it hasn’t been done yet.
November 7, 2007 at 10:50
There is a Wordpress export available for download as part of the BlogML release on CodePlex, but I don’t know if it’s been updated to be compatible with the latest release of Wordpress.
http://www.codeplex.com/BlogML