Keep your Wordpress permalinks after a Ghost migration

One of the last things that preventing me from migrating to Ghost as my full-time blogging platform was the inability to keep my permalinks intact. Since I have posts going back to 2009, I wanted to ensure that any links showing in Google search results kept people referred to the actual post rather than presenting a vistor with a 404 page.

Since Ghost is a relatively new blogging platform, documentation on such thinks as dynamic linking (permalinks) is rather scarce. I really had to dig around to find a solution.

Depending on the method of the code I wanted to implement, it would determine what file I would edit. For example, implementing a rewrite solution in the server.js file would require edits to be made in javascript. Unlike Wordpress, Ghost doesn't rely on PHP to run its backend, so any solution I was going to implement would have to be coded in javascript. Definitely not my language of choice.

After doing a ton of Google searches for 'Wordpress permalinks on Ghost' and variations thereof, I came across a code commit that was suggested on Github, containing the following key line of code:

server.get('/:year/:month/:day/:slug/', frontend.single);  

This was they key to rewriting the permalink structure in Ghost's chosen language. First a few details.

Wordpress allows you to construct permalinks with a simple /slug or with a more complex structure like /year/month/day/slug. Mostly everyone I know uses a more complex structure. My Wordpress installation was set to use the /year/month/slug structure, which meant that any links indexed by a search engine would include this information. Since Ghost doesn't natively follow this link structure, migrating my content to the new platform would cause links to break and throw a 404 error at visitor. Not the most user friendly of experiences.

Then I found the block of code mentioned above. Having previously examined the server.js file, I knew to enter the line of code under the ### Frontend routes section (starting on line 364). A quick tweak to write out the /:month code did the trick. This meant that Ghost would be instructed to accept anything posessing a valid year/month structure before the slug and process it as a valid URL. Under Wordpress this was a valid permalink:

http://www.classicyuppie.com/2013/11/get-junk-mail-prefix-back-os-x-mail-server-options/

Under the Ghost default, importing the posts would truncate the URL to this:

http://www.classicyuppie.com/get-junk-mail-prefix-back-os-x-mail-server-options/

Since Google had indexed the former, and not the later, the link would break. However, the new rewrite rule allows both to work. The only drawback - if you can call it that - is that anything matching a valid /year/month/day structure will resolve, regardless if it's the correct URL or not. For example:

http://www.classicyuppie.com/1243/01/get-junk-mail-prefix-back-os-x-mail-server-options/

This link will resolve to the same content, even though it wasn't published in January of the year 1243 (presumably because the Internet wasn't yet created). Essentially, it treats the year/month/day information as junk and omits it from the database query when it does the actual lookup. (Geek alert: Interestingly enough, it means that integers will also work, i.e. -1243).

For you early adopters that want to make the switch to Ghost from Wordpress, this is the perfect way to get your feet wet.

UPDATE: This workaround only works with Ghost 0.3.3. If you upgrade to v0.4, this rewrite method will break. Consider yourself warned.