How to upgrade a WordPress theme after you've hacked the heck out of it

Have you ever wanted to upgrade a heavily modified theme and seamlessly knit all your changes into the new code? Here's how.
Written by David Gewirtz, Senior Contributing Editor

Another big project of mine is a major migration of a legacy CMS to WordPress. I'll tell you all about it another time, but first, I wanted to get you excited about DIY-IT by giving you some hands-on how-to material you can put to work right away.

If you've ever worked with WordPress, you know one of its great appeals is the rich library of available themes. There's a vibrant commercial theme marketplace, filled with many talented designers.

Since WordPress is written in PHP, nearly all of its themes are available in source code, which means they can be customized. There are a few theme makers who (I think wrong-headedly) try to compress and encrypt their themes, but these folks are in the minority.

In any case, while you may choose to use a theme as-is, out of the box, I tend to heavily hack anything I can get my hands on, and that's certainly been the case with themes. The gotcha, of course, is I also like to take advantage of feature and security upgrades and that leads to an inevitable conflict: how do I use the new theme version, but knit all my changes seamlessly into the new code?

I've long used lab notes to keep track of my changes, but invariably I'll have to do a late-night emergency fix and and there have been (a few) occasions where I didn't get around to documenting it. So, I set out to find a solution driven by the code itself. I found one, it works exceptionally well, and (heh, I love this!) it's free.

There are essentially three main steps:

  1. Compare the original theme distribution with your changes and annotate your code
  2. Compare your annotated code to the new theme and merge your changes in
  3. Test the theme and upgrade supporting files

As it turns out, this process works out exceptionally well. I upgraded three sites in less than half a day, and each had a ton of changes that needed to be incorporated. Here's what I did.

Next: Find the changes (step 1) »

« Previous: Theme hacking

Find the changes

Step one of the process was to identify what I changed in the original theme code. I made moderately substantial changes to the original theme to handle the features provided by my AI Editor code. Those changes would have to be folded into the updated theme as well.

My plan for doing this was to find the original distribution source files for the old theme and then diff (compare) it against my changes. For each of my changes, I would then clearly comment the lines to show those are my changes to the code.

My big concern, once I decided on this strategy, was whether I'd retained the original distribution archive. I'm usually pretty good at keeping track of resources, but I hadn't touched this stuff for eight months, and anything could have happened.

As a backup, my lab notes would have guided me through the changes, but you never know if there's one patch here or one correction there that never made it into the lab notes. It's much more accurate to do an actual source code file compare.

Fortunately, I did have the original theme files and so I went ahead with my first diff. Key to making all this happen is a free piece of software called DiffMerge. DiffMerge is awwwwsome, works on Windows, Mac, and Linux, and quickly became my new favorite software tool. Diff, of course, has been around for years, but DiffMerge makes it just oh-so-simple.

The first phase of the process was pretty easy. Even though the live theme directory had 11,270 files in it, most of them were graphics and related non-code objects. Using DiffMerge on the original theme directory and on my modified theme directory, the program identified just 18 different source files that had been changed.

It took me just about an hour, using only DiffMerge, to go through my modified theme files and add "DG changed", "DG added", "DG modified" comments throughout the theme. This enabled me, later to see what changes in the updated theme were by the theme author and what changed I had to add when I knitted my code back into the updated theme.

All told, the first phase, finding and itemizing my changes in the code, took less than an hour for the first site. I was pretty psyched.

Next: Incorporate the changes (step 2) »

« Previous: Find the changes (step 1)

Incorporate changes in the updated theme

The next step was to incorporate my changes into the new theme distribution. Once I had a folder containing the old theme version, with my changes annotated, it was time to get the updated theme. I downloaded it, and created a second folder, which contained a factory-fresh copy of the vendor-provided theme update.

I ran DiffMerge on these two folders, one folder with my original modified theme, and the other folder containing the updated, factory-fresh theme. Since the two versions were about a year apart, there were quite a few changes between the two versions. DiffMerge identified all the changed files in the folder.

File-by-file, I went through and compared the files. If there were no highlighted lines in the old file with my "DG" marker, I just ignored the file. This was just an updated file.

But if there were lines marked "DG", I carefully copied over and modified the updated theme code, adding in my changes. In most cases, all that was involved was a simple menu selection, telling DiffMerge to either replace, insert, prepend, or append.

There were, of course, some bugs when I was done, but DiffMerge got me very close. Key to this is making sure the code I added into the new version also contains my "DG" markers, so if I have to do this again in the future, I'll be able to skip the first "search for my changes" stage.

All told, it took about 75 minutes to incorporate my changes into the updated theme. I've renamed the updated theme directory (the one that contains my changes) to a name that distinguishes it from the original vendor-provided theme.

So far, so good. But there's one more comparison run I wanted to do.

Next: Compare and test (step 3) »

« Previous: Incorporate the changes (step 2)

Compare the changes

It's important to note that, so far, I hadn't tried running anything in my theme. I had no idea (because I'd done no testing) if it would work. That was okay because I was still doing housekeeping.

One more piece of housekeeping I wanted to do was compare my newly-modified updated theme with the vendor-provided, factory-fresh updated theme. This time, I expected to see only my changes highlighted. I wanted to see if anything jumped out at me.

So, I uncompressed another version of the vendor-provided theme files, and I ran DiffMerge again. This time I compared the folder containing the updated theme with my changes against the updated theme without my changes.

As it turns out, there was an interesting difference. The theme author changed his way of displaying text strings from using _e() to esc_html_e() for most of his string output calls. By comparing just my code to his, I was able to see where these changes were made, and update my modifications to use the theme writer's new conventions...

...which turned out to be a very bad idea. As it turns out, this new function escapes out HTML tags and some of my modified code was generating HTML tags, which my slightly zealous hack had then just broken. Fortunately, since I'd marked all my code and was able to use DiffMerge to easily see my changes, it was quite simple to go back through and undo this particular "fix".

Yeah, it happens.

Check folder structure and images

Next up, it was time to check the folder structure of my original, modified theme and the newly modified, updated theme. I had changed a number of the images, particularly the place-holder logo, to reflect the identity of my site. I also added a number of custom image-holder folders my AI Publisher (the partner module to the AI Editor) code used for presentation of the site's content.

So, first, it was time to compare the old theme's image folder to the new theme's image folder. This I did outside of DiffMerge, choosing to rely instead on the old, Mark I Eyeball.

Load the newly updated, modified theme

It was time to load the new theme. On the server, I decided to do it the old-school way. I shut down Apache, and then I renamed the old theme folder, giving it the version number of the now-obsolete theme version. Then, using FileZilla over a secured tunnel, I uploaded my newly modified, updated theme. This took about an hour, so I figured this'd be a good time to lift some weights.

After a good workout session and an even nicer shower, I came sat back down at my desk and tried things out. It was all working and my themes had been properly updated.

So, if you've heavily hacked your themes (and this'll work for plug-ins and even other CMSs, too, I'm sure), download DiffMerge and use my three-step process. You'll thank me once you're done.

Stay tuned. We've got a lot more coming in DIY-IT including, yep, actual code. You're gonna love it!

If you've tried updating themes, tell us your experiences. Please note that I expect TalkBacks for project articles to be different from the tone on ZDNet Government. Please post constructive comments and helpful information only. Feel free to rant on my opinion pieces, but let’s try to keep these project discussions useful and information-packed.

Editorial standards