Rebuilding a WordPress Site in Phases

Ever since I started at Universal Yums, I’ve wanted to rebuild the WordPress theme. In its six years of existence style overrides have been layered on top of each other making new development really difficult. JavaScript was mostly in one massive file. The build system was outdated and clunky.

However, rebuilding a site that’s still in active development and has thousands of customers a day is tricky. You either freeze most development on the live site while the developers hide out and build a fresh theme (which wasn’t an option for us and has the risk of introducing too many bugs all at once), or very slowly refactor and rebuild the existing theme over time (which can be really difficult if you want to move to a completely new grid system or rip out Bootstrap v3 for example).

Or, maybe there is a third way?

It feels like a bit of a hack, but it definitely works. We found a method that allowed us to deploy a new theme in phases- one page or set of URLs at a time. This introduces much less risk and allows us to maintain a similar development velocity on the live site. The solution was to load the new theme for specific URLs as we completed development on them.

We’ve been successfully running on production for several weeks now with large amounts of traffic.

To start, we moved all the code in the existing theme that was not purely presentational into an mu-plugin, refactoring and adding unit tests as we went. Then we decided on a new theme base (with style library and build system) and got that set up. Finally, we picked a page that the design team had just refreshed, and built that in the new theme instead of the current one. To display in the site, we used filters to switch the theme just for that specific URL.

Here’s an example that switches the theme to “newtheme” when the “about” URL is loaded:

/**
 * Switches the theme for specific URLs.
 *
 * @param $theme
 *
 * @return string
 */
function prefix_change_theme( $theme ) {
	if ( strpos( $_SERVER['REQUEST_URI'], 'about' ) !== false ) {
		return 'newtheme';
	}

	return $theme;
}
add_filter( 'template', 'prefix_change_theme' );
add_filter( 'option_template', 'prefix_change_theme' );
add_filter( 'option_stylesheet', 'prefix_change_theme' );

Over time, as we refreshed or rebuilt additional pages, they could be loaded from the new theme rather than the existing one until the entire theme was switched over.

Caveats

If your site has performance plugins to minify or concatenate theme scripts and styles, you may run into issues. You can either disable those plugins or use filters so they don’t run on specific pages.

This also is not the best approach for all rebuilds. If the site is undergoing a large rebranding, rolling out the new theme incrementally will be a jarring experience for visitors as they navigate between pages. This approach works best if the headers and footers match in both themes and the design branding is largely similar.

About Devin

I am a developer based in Austin, Texas. I run a little theme shop called DevPress and help manage a WooCommerce shop with Universal Yums. Find me on twitter @devinsays.

Leave a Reply