Migration to WordPress from Movable Type on MacOS X and Linux

After three years of using Movable Type, I decided to migrate my weblog over to the open-source WordPress weblogging systems. This article documents the process, and some of the details.


Some of the reasons I decided to make this move included:

  • WordPress is open-source, and uses PHP. Movable Type is commercial software, and uses Perl. I know PHP fairly well, and I like free. I’ve quickly been able to get a global understanding of the system, and hack some things to my liking.
  • WordPress seems well documented and has a large support base
  • WordPress is dynamically driven, and everything is stored in a database. (I know that MT3 allows this.)
  • I find WordPress easier to use. For instance, I know that Movable Type supports the Markdown plug-in, but I never saw an obvious way to get it working — certainly nothing as easy as WordPress‘s “activate” in the Plug-ins window.
  • WordPress is full of niceties. For example, if you want pretty URLs, it’s just a click away, and WP will even create and manage the Apache mod_rewrite rules in a .htaccess file for you.
  • In WordPress‘s administrative interface, there is so much attention to detail (including the particular wording of some feedback messages), one gets the impression that the right kind of people are working on this thing.

The following sections document the process I followed.

Local setup and configuration

I decided to first setup my weblog on my local MacOS X system, so I could safely configure it and play around, until I felt comfortable enough to move the installation over to our production server.

  1. Installed MySQL using Complete MySQL.
  2. Used CocoaSQL to create a new database called wp_mattsweblog, create a new database user wordpress (and password) in the user table of the mysql database, associate the wordpress user to the wp_mattsweblog database in the db table of the “mysql” database. (At this point the DB is ready.)
  3. Create a new folder under ~/Sites called mattsweblog, under which I created the standard htdocs directory (that we use for the web accessible files, DocumentRoot). Added group writability to the htdocs directory, so that WordPress will later be able to write a .htaccess file there.
  4. Unpack the WordPress files within the htdocs directory.
  5. Create a new virtual host in /private/etc/httpd/httpd.conf
    <virtualhost *:80>
        ServerAdmin [email protected]
        DocumentRoot /Users/mhenders/Sites/matt.makalumedia.com/htdocs
        ServerName mattsweblog
        ErrorLog /Users/mhenders/Sites/matt.makalumedia.com/logs/error_log
        TransferLog /Users/mhenders/Sites/matt.makalumedia.com/logs/transfer_log
        AddType application/x-httpd-php .html
        AddType application/x-httpd-php .php
        <directory "/">
            AllowOverride All
  6. Use John Gruber’s AppleScript to restart the Apache webserver.

  7. Create a new “machine” in NetInfo Manager called mattsweblog pointing to (I did this by duplicating another entry.) This lets me access my local site via the URL via http://mattsweblog/
WordPress setup

Accessing the URL http://mattsweblog/, I was shown a welcome screen that pointed me to the WordPress installation link. I clicked on that link, and within about 30 seconds, my WordPress installation was up an running. WordPress created the administration user, and gave me the password.

I made the following customizations and modifications to my WordPress installation (in no particular order).
  • Theme. I decided to use the default Kubrick theme, but knew that I would be hacking it a bit, so I duplicated the theme (naming it mattsweblog), and edited its name in the style.css file, in order to distinguish it from the default, in the Themes area of the administrative interface. I then activated the mattsweblog theme, within the admin area.
  • Home link. Edited the template-functions-post.php file to create a static link under the dynamically built “Pages” section, to create a link to the “home page” (since clicking in the page header might not be obvious to all users.)
  • Markdown. Activated the Markdown plugin in the Plugins area of the admin interface. (The Markdown plugin lets you write your articles using the Markdown syntax, which is simpler and easier for humans to read, than HTML marked-up text.)
  • My own comments. I wanted the background color of my own comments to be different, so I added the following to the comments.php file: < ?php if((get_comment_author() == "Matt Henderson") or (get_comment_author() == "mhenders")) { $oddcomment = "self"; } ?> I then edited the style.css file, duplicating the .alt class, and changing the background color to something yellowish.

  • Permalinks. In the Options -> Permalinks admin area, I changed the permalinks structure to one of the proposed defaults (http://weblog/2005/01/05/article-name).
  • Content area. I decided that in order to keep the file system clean, I would put anything specific to my weblog in a directory called content/ which sits at the root of the htdocs directory. In here, I put images, php libraries, you name it.
  • Spam Protection. I added the WP-Gatekeeper simple spam prevention plugin, that asks the user a simple question to be answered when posting a comment (like, “What color is an orange?”).

Migrating Movable Type data


p>At this point, I was ready to import my Movable Type data into my WordPress installation. I followed the MT migration procedure pretty much to the letter, and ended up with a import.txt file on my local system, containing my MT data.

I opened the file in BBEdit, and Process Lines Containing... to locate all the places on http://matt.makalumedia.com where I’d referenced images, files, etc. I then moved all those resources from the server to my local setup into my content/ directory, using Transmit, my SFTP client. (Fortunately, there were no name clashes.)

Once that was done, I used BBEdit‘s grep function to change all absolute resource references in my MT data file to relatively reference the resources in content/.

Next, I used BBEdit‘s grep feature to remove all Ping blocks, since probably 99.9% of those were spam. (I think I could have done this easier via SQL query to the DB.)

As per the MT migration procedure, I then imported the MT data file into WordPress. It worked without a hitch.

Finally, I issued this SQL statement to the database, using CocoaSQL in order to empty all the excerpts (since I’ve always been in the habit of copying the full article body into the excerpt):

`update wp_posts set post_excerpt = "";`
Redirecting old URLs

The next thing to tackle was the handling of old URLs. In MT, my old URLs looked like:


Since a couple of people out there (and Google) have linked to some of my articles, I want to make sure they continue working. And, perhaps most importantly, I want to make sure all those RSS feeds still continue to work.

The Apache web server has a module called mod_redirect that can handle redirecting one URL to another. The module gets its information from either httpd.conf file or a websites local .htaccess file. Fortunately, mod_rewrite is enabled by default in Mac OS X systems.

So, I added the following to the local .htaccess file which WordPress created when I updated the Permalinks settings:

ErrorDocument 404 /index.php?error=404
RewriteRule index.rdf /index.php?feed=rdf
RewriteRule index.rss /index.php?feed=rss
RewriteRule index.xml /index.php?feed=rss2
RewriteRule archives/000833.html /index.php?p=160
RewriteRule archives/001556.html /index.php?p=177

That’s not an exhaustive list, but you get the idea.

  • The first line tells the web server to redirect 404 errors (document not found) to WordPress‘s own handler, based on the 404.php file found in the Theme.
  • The next three lines redirect the old RSS feeds to the new feed URLs
  • The last two redirect specific old article URLs to their new equivalent.

And, as per described by the wonderful support community, the “additions” should be kept outside the WordPress managed block within the .htaccess file, indicated by # BEGIN WordPress.

Instead of setting up redirects to all my articles, I’ve decided to add the following to my 404.php WP script:

        < ?php
            $exceptions = array('favicon','robots.txt');
            $sendEmail = true;
            foreach($exceptions as $exception) {
                if(eregi($exception,$_SERVER["REQUEST_URI"])) {
                    $sendEmail = false;
            if($sendEmail == true) {
                 $to = '[email protected]';
                $from = '[email protected]';
                $subject = 'Weblog 404: '.$_SERVER["REQUEST_URI"];
                $message = "";
                foreach( $_SERVER as $key => $value) {
                    $message .= $key." : ".$value."n";
                mail($to,$subject,$message,"From: $from");

This PHP code sends me an email with the details regarding failed requested URLs (and lets me maintain a list of exclusions, like favicon). I’ll monitor these emails for a while, adding frequently requested files to the .htaccess file (and then remove this code when I’m comfortable that things are stable.)

Moving it all to the operational server.

After creating some content Pages (like “About”, “Contact”, etc.), I was satisfied with the local setup, and ready to move everything over to the operational (Linux) server.

  1. I first had our system administrator create the necessary database and user in MySQL.
  2. He then setup a web area under matt2.makalumedia.com. My strategy was to setup the site under matt2, and then switch over matt once I was happy.
  3. I copied over all my files under my local htdocs directory to the equivalent directory on the server.
  4. Again used CocoaSQL to create a dump of my local WordPress database to a .sql file. My sysadmin was worried about feeding a UTF-8 encoded file to our production MySQL server, so before moving the .sql file to the server, I re-encoded it to Western Latin-1 using BBEdit. (I don’t write using extended characters that often, so I knew this wouldn’t be a big deal.)
  5. Did a search and replace in the .sql file for http://mattsweblog to http://matt.makalumedia.com, so that the site would work once the data was imported on the server. (Well, actually I didn’t do this, and later regretted it.)
  6. I then uploaded a zipped copy of the .sql file to the server, and the system administrator imported it to the MySQL database. At this point, the site was pretty much running properly.
  7. Once I was happy that matt2.makalumedia.com was working, the system administrator added matt.makalumedia.com as a ServerAlias to the matt2 virtual host, and restarted Apache.

At this point, the new weblog was up and running on the server with WordPress.

Hope this article helps anyone out there looking to do the same. Don’t hesitate to ask if you have any questions.

9 thoughts on “Migration to WordPress from Movable Type on MacOS X and Linux”

  1. In my opinion, Spam Karma 2 is a much better spam protection tool. 99.9% of the time, commentors on your blog won’t even know it’s there.

    It works by giving each comment a score based on a bunch of things like the number of links in a comment and whether any of them link back to this site (spammers rarely do), if a Javascript payload matches (but won’t kill a comment if a user has JS off), past comments (i.e. spammers will keep spamming), etc.

    I’d also suggest Bad Behavior to block spam bots from ever getting to your site in the first place, but some people complain that it occasionally gives false positives and thinks real people are bots. I’ve never seen it happen and only had it happen to someone on my site once, so I dunno.

    Anyway, welcome to the world of WordPress! πŸ™‚

  2. I think that in general, geeks who “design” use WordPress. Designers who “geek” use MT. I don’t know that such generalizations are worth anything, but WordPress users are generally quick to point out software specifications whereas MT users tend to just use the software.

    Anyway, glad you found something else to upgrade πŸ˜‰

  3. Hello matt, I was searching the web and found your article “Migration to WordPress from Movable Type on MacOS X and Linux”. I really like your blog and found it worth while reading through the posts. I am looking to publish a comprehensive site reviewing many different articles and blogg. Please feel free to take a look at my blog at and add anything your want.

Agree? Disagree? What do you think?