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.
Why?
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.
- Installed MySQL using Complete MySQL.
- Used CocoaSQL to create a new database called
wp_mattsweblog
, create a new database userwordpress
(and password) in theuser
table of themysql
database, associate thewordpress
user to thewp_mattsweblog
database in thedb
table of the "mysql" database. (At this point the DB is ready.) - Create a new folder under
~/Sites
calledmattsweblog
, under which I created the standardhtdocs
directory (that we use for the web accessible files,DocumentRoot
). Added group writability to thehtdocs
directory, so that WordPress will later be able to write a.htaccess
file there. - Unpack the WordPress files within the
htdocs
directory. - Create a new virtual host in
/private/etc/httpd/httpd.conf
<virtualhost *:80>
ServerAdmin matt@makalumedia.com
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
</directory>
</virtualhost>
- Use John Gruber's AppleScript to restart the Apache webserver.
- Create a new "machine" in NetInfo Manager called
mattsweblog
pointing to 127.0.0.1. (I did this by duplicating another entry.) This lets me access my local site via the URL viahttp://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.
Customization
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 thestyle.css
file, in order to distinguish it from the default, in the Themes area of the administrative interface. I then activated themattsweblog
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 thehtdocs
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
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:
http://matt.makaumedia.com/archives/000833.html
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 = 'matt@makalumedia.com';
$from = 'matt@makalumedia.com';
$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.
- I first had our system administrator create the necessary database and user in MySQL.
- He then setup a web area under
matt2.makalumedia.com
. My strategy was to setup the site undermatt2
, and then switch overmatt
once I was happy. - I copied over all my files under my local
htdocs
directory to the equivalent directory on the server. - 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.) - Did a search and replace in the
.sql
file forhttp://mattsweblog
tohttp://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.) - 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. - Once I was happy that
matt2.makalumedia.com
was working, the system administrator addedmatt.makalumedia.com
as aServerAlias
to thematt2
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.
Enjoy this article? — You can find similar content via the category and tag links below.
Categories — Technology
Questions or comments? — Feel free to email me using the contact form below, or reach out on Twitter.