Why did we do it?
As a company, we’ve increasingly been moving away from Wordpress as a platform. Our site has been based on Wordpress since we first relaunched it in 2010. Although it has served us well down the years, its limitations as a 'proper' CMS have become obvious. Last year, we gave Craft a go and immediately loved it—we even blogged about it at the time.
Since then, we’ve built half a dozen websites in Craft and using it has become somewhat ingrained in our development process. We even wrote a framework for deploying Craft websites—the imaginatively-titled CraftDeploy.
Eating your own dog food
There's a product design term 'dogfooding' that refers to the practise of using your own product in order to better understand it. Seeing as building Craft websites is very much part of the Toward 'product' we sell to clients it seems appropriate to use it ourselves. Doing so provides our whole team a better understanding of how it works—hopefully this can influence how we think about our own products as we sell, design and build them.
The Matrix
Another compelling reason is to move beyond the constraints of the WYSIWYG editor. Due to Craft’s excellent ‘Matrix’ content type, we can exert a lot more control over our content allowing us to do fancy things like placing a call-to-action wherever want.
The potential for this is almost limitless. Being able to give content authors the tools to easily place not only traditional content types but actual functionality in their articles or pages opens up a world of possibilities. We've been raving about this to clients and so it made perfect sense to see what it can do for us. Combine this with some sort of analytics (eg. event tracking) and you can really start to explore more effective ways of achieving business objectives.
Migrating content
The first (and most important) challenge was to figure out if we could export our current content (including several years worth of blog posts) into a format that could be imported in to Craft. Fortunately, we’d already done a similar thing on a previous project and knew that there was a great Craft plugin available that would import CSV data—the aptly titled ‘Import’ plugin from prominent developer Bob Olde Hampsink. Furthermore, exporting the content from Wordpress couldn’t be easier either thanks to another excellent plugin WP CSV.
Before importing the content, it was just a case of setting up the relevant fields, sections and entry types we wanted to import into. Once this is done, we mapped the fields in the CSV to the relevant place and imported the content. Boom!
Images
Once the content is in the database, there was still quite a lot to do before it could be used. The challenge was dealing with image uploads. Fortunately, when you use an image in Wordpress, it stores a direct reference to the URL of the image meaning it’s easily portable (assuming the path of the image doesn’t change). As anyone who has worked on Wordpress sites will know—this is a pain when deploying the site between your various environments as the domain will often change. For example, my local development environment uses ‘toward.studio’ as the domain, whereas the live environment is ‘toward.studio’. This means that you have do a find and replace of all these image paths every time you switch environments.
Fortunately, we don’t need this to happen with the Craft website so we can just run a find and replace query on our newly imported data. This was a great time to move our assets on to a CDN, so we did just that:
Furthermore, Craft will actually index anything it finds in the designated 'assets' folders so importing all the images for future use is possible. One issue here is that Wordpress generates various copies of images in all the sizes it needs, so there’s a lot of versions of images you'll probably never need. Not a huge problem unless you’re OCD about this sort of thing.
Shortcodes
The next challenge was that of translating Wordpress’ shortcodes into something usable. For the uninitiated, Wordpress uses a system called 'shortcodes' to deal with the problem of inserting non-text content types into content. A simple example might be a video shortcode which looks like this:
[video src='dancing-kittens.mp4']
Wordpress will 'parse' this and output your dancing kittens video on the page. Again, a plugin came to the rescue here in the form of Shortcodes for Craft CMS. Handily, this meant that we could write our own markup to deal with the various images, captions, galleries and videos that we’ve embedded in our content down the years. Sorted!
Business logic
Our final challenge was to port any so-called 'business logic' to the new website. Some examples of this are the contact form handling and the code that facilitates loading blog posts over AJAX. Wordpress developers will be familiar with the "functions.php" file that typically contains this sort of code.
Again, we used a plugin here—the Business Logic plugin we use in all our Craft websites. Not strictly a ‘plugin’ in the sense that is doesn’t do anything out-of-the-box, it just provides a nice boilerplate for writing your own logic. Moving our code over was pretty easy as the vast majority of it was no longer needed as it was Wordpress-specific and isn't needed in Craft. This is one of the things that makes Craft so great!
Now we have all our content and business logic in place, it was simply a case of going through each Wordpress template and porting code from PHP to Twig. This was actually incredibly easy as we’d already done a good job of keeping things organised and modular in the Wordpress site. Of course, some bugs were created but nothing serious and all were squished in due course.
301 redirects
As part of the transition we were keen to move our blog posts from the Wordpress default of being in the root directory to a new '/blog' URL. For the uninitiated, a 301 redirect is a thing we use to tell Google (et al) that a page has moved permanently from one URL to another. This is essential work as it prevents Google from assuming the page has gone (and possibly penalising your ranking). So when we moved our blog URLs we needed to somehow redirect every post to it's new home.
After battling unsuccessfully with 301 redirects for a while it occurred to me that this could be done in Craft itself by intercepting potential 404s (because the old page no longer exists) and searching for the ‘slug’ of that in our Blog. If it finds the post, it redirects. If not, the page genuinely doesn’t exist and you are treated to our world famous 404 page. You can see how this works in the code below, located in our business logic plugin.
if (craft()->request->isSiteRequest()) { $inRoot = ((craft()->request->getSegment(2) === null) && (craft()->request->getSegment(1) !== null)); if ($inRoot) { $criteria = craft()->elements->getCriteria(ElementType::Entry); $criteria->section = 'blog'; $criteria->slug = craft()->request->getSegment(1); $entry = $criteria->first(); if ($entry) { craft()->request->redirect($entry->url, true, 301); } } }
Geshi
This leads us neatly in to a small plugin I wrote as part of the process. Sometimes we need to show code in blog posts and syntax highlighting is a really useful feature to present code in a legible way. Luckily, there are tons of solutions for doing this—none were available for Craft however. I'd used the excellent Geshi library in the past via a Wordpress plugin so I decided to bring that feature to Craft with the plugin Twig Geshi.
We've got some great plans for our website and the speed and ease of developing with Craft will help us iterate quickly. We're looking forward to the greater control Craft and the Matrix will give us over our case-studies and blog posts in future, so expect a lot more developments in those areas.
Have you ported a site from Wordpress to Craft? Did we miss anything? We'd love to know, so drop us a tweet or an email.
If you'd like more creative control over your content maybe Craft is the CMS for you. If you'd like to talk about a rebuild project, feel free to get in touch.