The nature of our upcoming site theme refresh provided me with an interesting challenge:

Project requirements

  1. Keep the production site alive and in use during development.
  2. Don’t enforce a content freeze on production during development.
  3. Have a development site available for page building and review.
  4. Provide a mechanism for the development team to be notified about content changes in the production environment.
  5. Only update certain post/page content for pages with given ID numbers.
  6. Manipulate certain post meta fields for specific pages.
  7. Ensure no IDs change or get created during the deployment process.
  8. Deploy changes on launch day to production quickly, en masse, and with minimal staff.

We’ve always had a DEV site, but the trouble we always faced was how we get content from DEV up to PROD once it was ready.  There were a few options, but each had drawbacks:

  • WordPress import tool.  This tool has unpredictable results and is designed for whole-site importing, not necessarily for importing selections of content.  Instead of updating existing page content, it might add new posts and create duplicate content.  It could also change IDs of existing pages, and there’s no simple way to monitor what it’s doing.
  • SQL import.  On a complex multisite setup such as ours, the idea of trying to target updates to only certain posts and certain post meta fields is theoretically possible, but in reality would be a logistical nightmare.
  • Popular WordPress migration tools.  There’s a bunch out there, but not all of them work well with multisite, or specific subsets of migration data.  Also, there isn’t enough time to evaluate each one.  More importantly, selecting a plugin tool puts the migration in a vulnerable spot – if there’s a bug with the migration tool that we don’t discover until launch day, this could threaten the success of our launch.
  • Manually copy-and-paste content changes.  No joke, it’s actually a proven method and we have had a lot of success with it.  Yes, it’s an archaic and tedious method, but for small deployments it’s a realistic deployment method.  There are actually some benefits to this method, including: no surprises, and assured personal review of each page migrated.  But, in our current case of migrating hundreds of pages, this method is not practical, and no one wants to volunteer to give up their weekend to do a task that’s this laborious.

I decided to see if WP CLI offered the functionality required, and it turns out that it does, and does so beautifully.  In order to be a viable option, WP CLI needed to be able to do the following things:

  • Change page templates in bulk – YES.
  • List ID numbers for all pages – YES.
  • List ID numbers for all pages with a certain parent – YES.
  • Export and import page meta fields – YES.
  • Export and import page content – YES.

Having this tool available for our use will be a tremendous benefit for deployment.  Since it works on individual pages and can manipulate post meta keys one-by-one, we can use it to change items in a controlled and predictable manner.  The tool’s popularity and simple, focused design builds my confidence that it will work reliably now during pre-deployment tests as well as under the pressure of launch day in a few weeks from now.

On launch day, the overall process for our migration will be as follows.

  • Use WP CLI to list all page IDs that we want to migrate, storing that as a list for future reference.
    wp post list --post_type=page --url=dev.domain.com
  • For each of those page IDs, export the page content:
    wp post get [POST-ID] --field=content > content-[POST-ID].txt
  • For each of those same page IDs, export the page meta fields we want to migrate:
    wp post meta get [POST-ID] [META-KEY] > meta-key-name-[POST-ID].txt
  • The resulting TXT files store all of the content from DEV that we want to upload to PROD.  All that’s left is to get those files to PROD and run the complementary WP CLI commands to load the changes into the production site.

The only gotcha here is that any changes made to the page content on PROD during the development phase (1-2 weeks) will not be automatically brought over to DEV.  This is good in some cases (we have a lot of content that we don’t want to synchronize as a part of this migration), but it creates a situation where updated content on PROD would be lost if we imported the DEV content.  Since our site page content is relatively static, we can manually keep track of any page changes and make them manually to DEV during the development phase.

To help notify us of changes to PROD, we run a plugin that emails us with any changes to site page content.  If an editor makes changes to PROD content during the development period we can mirror those changes on DEV.  We have also asked the larger team of site editors to email us if they make any changes so that we can ensure they are synchronized in DEV and not lost during the launch.

In conclusion, I’m happy to report that our migration will be successful and won’t require us to work long hours doing tedious tasks over launch weekend, all thanks to WP CLI.  I’m very grateful that we have a powerful tool like this available at our disposal, and my team is happy they won’t be asked to work during their weekend time off.