Moving a WordPress site

If you ever find yourself in the unfortunate position of having to work with wordpress, you may have run into problems when deploying to live. Imagine you’ve got a wordpress site all set up locally and you’re ready to deploy to an expectant client. You might have used a custom theme, entered the content for the client and maybe diddled with the source files a bit, but it’s all working locally so what could possibly go wrong? Surely this is just a case of changing the config file, ftp’ing up the scripts and restoring the database right?

Erm… no.

Lots can go wrong.

  • You might find that once the site is live it still tries to direct you to localhost.
  • You might find you lose all your theme options if you’ve used a paid theme.
  • You might find that some of the content is gone, or hyperlinks within the content are still linking to localhost.


A lot of these issues are caused by hard-coded urls going into the database, and these don’t automatically update when you switch to live.  A simple find-replace on the SQL file won’t do it either because some plugins and themes work out their caching by counting the number of characters in a database field, and if you change it without going through the various script hooks you’re going to mess it up. Deploying a WordPress site to live *should* be a doddle, but things can go wrong. Below is the recipe we found works best when doing the first push to live.


Make sure the site is working as you want it locally. Once you’re sure it’s working and connected to a database and so on, back up both the site and the DB and keep them safe as the next steps will alter both.

Preparing the database

Save yourself many headaches and get hold of a copy of the wordpress command line tool ( – installation instructions are on the site.

Once that’s installed, navigate your terminal into the root folder of the site you want to put live and enter the following commands (remembering to add a port to “localhost” if you’re using a different port, and replacing “” with your live domain name):

wp search-replace 'localhost' ''

You will then see all the tables that got updated (make sure there’s some numbers in there so you can be sure that it did find/replace the domains!). Next there are two settings in the wp-options table. You can update these on the menu in the wordpress console, but you can’t get to the menu when it’s live because the site uses these settings to direct you to the homepage etc. so you need to change them before going live. If you try and update them in the dashboard of your local version, it’ll break your local version too because THAT will try to get to the live url. It’s a catch-22! wp cli helps again, these two commands will update those settings;

wp option update home ''
wp option update siteurl ''

Then back it up. That’s the database you’ll restore to live.

Edit the config

Just one last script to go. In the site’s root folder you’ll find a file called “wp-config.php”. There are four database related fields in there that you need to update to the live equivalents, which are “DB_NAME”, “DB_USER”, “DB_PASSWORD” and “DB_HOST”. If you don’t already know these, your hosting provider should be able to tell you (or, it’ll tell you while you’re setting it all up).

Good to go!

With all that done, just ftp the files up to where you want them and import your local database to live. Update DNS and you should be cooking!

I hate wordpress. The irony that this is a WordPress blog is not lost on me 🙂


Concrete5 custom theme cheat sheet


This is a cheat sheet for setting up a custom theme in the current release of the awesome CMS “Concrete5” (which at time of writing is 5.5). This assumes that you have a bunch of static html files and you have your design all up and running within a file system. These are the basic steps to go through when you come to “concrete-fying” your site.

If you haven’t checked out Concrete5 yet, you definately should!

This is not meant to be a comprehensive guide, it’s just a quick step-by-step. Assumes knowledge of concrete5, php and basic front end. If anyone finds it useful then great.

These are, in order, the steps I go through to get a basic html template up and running in Concrete 5.

Basic Setup

Put all your html/js/css in a folder under the concrete5/themes folder

Create an additional file called “Description.txt” in that folder, first line is the title of the theme, second line is a short description.

Copy/paste the most “typical” html file in your collection, rename it “default.php”. Then within default.php…
Paste this after opening head tag:
<?php Loader::element('header_required'); ?>
Paste this before closing body tag:
<?php Loader::element('footer_required'); ?>
If you have a copyright line, use this to auto-populate date:
<?php print date('Y') . ' ' . SITE; ?>
Any relative links to stylesheets, replace with this:
<?php print $this->getStyleSheet('css/your_style_sheet.css'); ?>
Any other relative links (e.g. images, javascripts) should have this pasted before the path
<?php print $this->getThemePath(); ?>
Inside the theme folder, create a new folder called “elements” and two blank php files called “header.php” and “footer.php”

Grab all content that is “common to the top” of every page on your site (typically everything down to and including the opening body tag) and paste it into “header.php”

Grab all content that is “common to the bottom” of every page on your site (typically javascripts and the closing body/html tags) and paste it into “footer.php”

Where the header and footer used to be, place the following;
<?php include("elements/header.php"); ?>

If you have a jquery link in your templates, delete it, concrete5 will put one of these in and you can

Create editable sections

Replace global/local areas of editable content with the following (change string for each one);

<?php $a = new Area('Main'); $a-->display($c); ?>
<?php $a = new GlobalArea('HeroText'); $a-->display($c); ?>

Once they’re added, install the theme and check you have it all set up correctly. This is a good time to splat any bugs as common ones will arise at this point. Particularly common ones are;

  • Your CSS styles are conflicting with concrete 5’s css files (this will produce effects like the editable hover block / edit interface looking a bit screwy)
  • Your javascripts conflicting with the concrete5 javascripts. NOTE: make sure you haven’t included two jquerys (check console for errors).

Sorting out the nav

Add all pages in as you want them, then set up the nav. To do this;

  1. Create a folder – (root)/blocks/autonav/templates
  2. Copy the file “view.php” from (root)/concrete/blocks/templates/view.php and put it in your newly created folder
  3. rename the file to something like “header_nav_template.php”
  4. Edit the file to put in whatever custom html you want (the file is very well commented)
  5. Because we don’t really want the user adding or deleting the nav, we can hard code this block into the view using the following (replace with any options you want);

$bt = BlockType::getByHandle('autonav');
$bt->controller->displayPages = 'top';
$bt->controller->orderBy = 'display_asc';

The setup is similar for doing breadcrumb style navs, but you insteadyou are overriding “concrete/autonav/templates/breadcrumbs” (which you copy into the same folder as above). Then to hard code this into your view you use;

$autonav = BlockType::getByHandle('autonav');
$autonav->controller->orderBy = 'display_asc';
$autonav->controller->displayPages = 'top';
$autonav->controller->displaySubPages = 'relevant_breadcrumb';

Set up your various page types

Copy/paste your “default.php” page, rename it to each of the page-types you want within your site, e.g. “2-column.php”, “home.php”. You can make any ammendments to each of these at this stage (e.g. change markup, any additional editable content areas and so on).

Once you have done this for all your templates, you can pretty safely delete any remaining html files within the theme folder.

If you uninstall/reinstall your theme, concrete5 will see these new files and will then add in the nessecary database rows to get them all set up.