ChronicBabe.com started off as a smallish blog, and was powered by Movable Type. But as the site grew, features were added, and we soon started to feel a bit limited by good ol’ MT, even with it’s extensive range of plug-ins. I had been working on my own content management system, and ChronicBabe.com founder Jenni was up for making the switch.
One of the main priorities of switching to a new CMS is to preserve your existing page links if your new system will have a different URL structure. For example, if your old site has a page like:
http://www.some-site.com/articles/2007/12/8/some-post.php
And the same post on the new site will be different than that, say:
http://www.some-site.com/articles/123
Or anything else that’s different, you want to make sure that the 1st link redirects correctly, for several reasons:
- You don’t want to aggravate those that have bookmarked your pages
- You don’t want to lose traffic from websites that have linked to your articles, and…
- Until Google updates itself with your new links, you want to ensure that the old ones still work so you don’t lose search engine traffic.
Fortunately, Movable Type’s database structure has a field we can manipulate.
Hacking the “mt_base” Database Field
If you’ve administered Movable Type to any degree, you may have wondered why they make you choose a page extension (.html, .php, .htm, etc.). Every entry in MT has a “slug” that’s typically auto-generated. For example, if you write an article called “Shrubbery Rulez” - the slug might be “shrubbery_rulez”, and it gets stored in the “mt_base” field of the “mt_entries” table (it’s been awhile since I’ve used MT, so maybe this is slightly different now…). Then, when MT assembles your page, it slaps the slug together with your chosen page extension. So if you selected “php” as your extension, this will generate a page called “shrubbery_rulez.php.”
When I exported all the entries from MT, I kept the mt_base field in my new database structure.
If we didn’t have that many pages to redirect, I would simply put some redirects into an .htaccess file, like this:
RewriteRule extras/index.php?id=contact http://www.chronicbabe.com/contact/ [R=301,L]
The old page goes on the left, the new on the right. The “R=301″ sends what’s called a “header” which flags this as a permanent move of the page, and that any search engines hitting this should go ahead and update their records. The “L” means that this is the last rule to apply - don’t bother reading any further.
But since we have quite a few articles to work with, let’s bypass this route and use PHP to determine if a redirect is necessary, and if so, where to redirect to. We’ll still send a 301 page header, which is crucial for maintaining search engine rankings.
PHP Page Redirects
While we’re mainly using PHP here, we still get a little help from our .htaccess file, with this line:
# MT id hack RewriteRule articles/[0-9]+/[0-9]+/([a-zA-Z0-9_]+)\.php$ /articles/$1/ [L]
This checks for the old MT URL structure, and uses a regular expression to chop off the last part of the URL (shrubbery_rulez.php), chop off the extention (.php), and pass it to our new URL structure so that it will look like this:
http://www.chronicbabe.com/articles/shubbery_rulez/
I knew that the new URL structure would end with an ID field that would be numeric. So at the top of the script that pulls articles from the database, I checked to see if the ending part of URL was numeric or not, like so:
if (is_numeric($_GET['id'])) {
$id = $_GET['id'];
} else {
$id = mysql_escape_string($_GET['id']);
$mt_id = 1;
}
Using PHP’s is_numeric() function, I code a basic conditional that checks if we have a number, which would indicate all we have to do is pass this number to our SQL query. However, if it’s not a number, we need clean it up with mysql_escape_string(), and then I create a “true” value for a variable called $mt_id.
Later in the script when I actually pull an article from the database, I check for this variable, search the database for a match, pull the numeric ID, and finally perform the 301 redirect like so:
if ($mt_id) {
$sql = 'SELECT article_id FROM articles WHERE mt_base="'.$id.'"';
$row = $db->getRow($sql);
header("HTTP/1.1 301 Moved Permanently");
header("Location: /articles/$row[0]/");
exit();
}
I use the handy PHP header() function to send the 301 redirect code, and then perform the actual redirection.
By taking a little extra time and doing this correctly, the transition from the old CMS to the new was seamless. While not all transitions may occur like this, hopefully there’s enough info here to get you going in the right direction - cheers!
Very interesting…