Managing Your WordPress Site with Git and Composer Part 2 – Using Composer to Manage Themes and Plugins

#
By Gilbert Pellegrom

In part 1 we looked at how to store and manage your WordPress site in Git, however we deliberately didn’t include anything in the wp-content folder in our Git repo. This means that you would need to manually migrate any themes and plugins that you have installed on your site.

One way to get around manually having to migrate your themes and plugins using our method is to use Composer (a package manager for PHP), so in this post we’ll be looking at how you can use it to manage the themes and plugins we didn’t store in our Git repository last time.

What is Composer?

Composer is the defacto package manager for PHP. Package managers have become very popular in recent years in the web development scene as they allow developers to package and distribute their work in an easy and free manner. If you’ve ever worked with Node.js, npm is the equivalent package manager for Node.js. Composer allows you to install and update packages from the command line, using a single composer.json file to specify which packages to manage.

We are going to use Composer combined with a special WordPress-specific package repository called WordPress Packagist to install our themes and plugins.

Install Composer

Let’s get started by installing Composer:

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/local/bin/composer

You should now be able to run composer from the command line. If for whatever reason something didn’t work, check out the Composer installation instructions for help.

composer.json

The WordPress Packagist site helps us out here by mirroring the WordPress plugin and theme directories as a Composer repository. We can specify which plugins and themes we want to install in our composer.json file. So lets get started by creating our composer.json file in the root of our project:

touch composer.json
nano composer.json

Next let’s define our project and specify which plugins and themes we want to install. Add the following to the composer.json:

{
    "repositories": [
        {
            "type": "composer",
            "url": "http://wpackagist.org"
        }
    ],
    "require": {
        "wpackagist-plugin/akismet": "3.1.1",
        "wpackagist-theme/evolve": "*"
    }
}

What’s going on here? First we add wpackagist.org as a custom composer repository. We need to do this so composer can find the WordPress Packagist plugins and themes. Then in the “require” section we define the plugins and themes we want to install. In this case we’re installing the Akismet plugin and the Evolve theme. You can install a specific version (e.g. "3.1.1") or just let composer install the latest version (e.g. "*").

Save and exit composer.json. Now lets actually install our plugins and themes by running

composer install

Hopefully you should see something like this:

composer-install

Great, now you have a good way to manage themes and plugins without having to store them in Git. Remember that you should store your composer.json file in Git.

Deployments and Updates

It’s worth noting at this point if you deploy your Git repository you will need to run composer install (the first time you deploy) or composer update (every subsequent time you deploy) on every server that you deploy your site to. Deployment strategies are outside the scope of this article, suffice to say you will need to be able to SSH to your server.

Once your site is deployed there are two ways you can keep your themes and plugins up-to-date. You can continue to use the WordPress admin as you would normally to update any themes and plugins you have installed (you don’t have to worry about breaking your install or being “out-of-sync” with your composer.json), or you can manually login (SSH) to your server and run composer update. Both methods will achieve the same outcome and you can mix and match without concern.

Another option you have is to do what I have done on my own personal site recently and created a must-use plugin to automatically run composer update twice a day on my server. See the source code and feel free to use it on your own sites. Note that to make the script work you will need to add the following to your wp-config.php to let the script know where composer is installed:

define( 'COMPOSER_PATH', ‘/path/to/composer' );

Warning: If you are using this method to update plugins there is a possibility that breaking changes might be introduced if a plugin is updated. To get around this you can either be very specific about the versions of plugins you are installing, or just make sure you check your site regularly for breaking changes. Also this plugin uses PHP Namespaces which means your server will need to be running PHP 5.3+.

Installing Premium Themes and Plugins

If the theme/plugin author supports it, you can install certain premium WordPress themes and plugins using Composer too. For example we allow users to install WP Migrate DB Pro via Composer. To do this you need to add extra repositories to the composer.json file for each theme or plugin you want to install, and you need to add some extra information so Composer knows where to install the themes and plugins.

"require": {
    "deliciousbrains/wp-migrate-db-pro": "*"
},
"repositories": [
    {
        "type": "package",
        "package": {
            "name": "deliciousbrains/wp-migrate-db-pro",
            "type": "wordpress-plugin",
            "version": "1.5",
            "dist": {
                "type": "zip",
                "url": "https://deliciousbrains.com/dl/wp-migrate-db-pro-latest.zip?licence_key=<LICENSE_KEY>&site_url=composer-test.dev"
            },
            "require": {
                "composer/installers": "v1.0.7"
            }
        }
    }
],
"extra": {
    "installer-paths": {
        "wp-content/plugins/{$name}/": ["type:wordpress-plugin"],
        "wp-content/themes/{$name}/": ["type:wordpress-theme"]
    }
}

Custom Themes & Plugins

“What if I have a custom theme or plugin?” I hear you ask? Well that situation might be simpler than you think. You can simply store your custom theme or plugin in your Git repository like any other files. Using composer to install official themes and plugins will have no effect on your custom themes and plugins and both can live together in complete harmony (even though one is stored in Git and the other isn’t). I know earlier we talked about not storing anything in the wp-content folder, however this is one situation where it makes sense to break that rule.

One brilliant example of when to do this is when you need to customise a theme you have installed using Composer. Let’s say you have installed the Evolve theme using Composer and the theme now resides in:

wp-content/themes/evolve

Instead of customising the theme code (and losing your changes when you run composer update) you can create a child theme and store the child theme in your Git repo. This would give you a folder structure like:

wp-content/themes/evolve       # installed via composer
wp-content/themes/evolve-child # stored in git

As we talked about in part 1, to store the “evolve-child” theme folder in Git you will need to modify your .gitignore file so that it doesn’t ignore this folder and its files but does continue to ignore everything else in wp-content. In this case the lines you would need to add to .gitignore would look like this:

# Don’t ignore themes dir, but ignore everything inside
!/wp-content/themes
/wp-content/themes/*

# Don’t ignore evolve-child theme
!/wp-content/themes/evolve-child

Now you can run composer update as much as you like and not lose and changes you make, as all of the customised code is stored in Git.

That’s it for part 2. In the next post we’ll be looking at how to use Git Submodules (as an alternative to Composer) to manage your plugins and themes for your Git stored WordPress site.

About the Author

Gilbert Pellegrom

Gilbert loves to build software. From jQuery scripts to WordPress plugins to full blown SaaS apps, Gilbert has been creating elegant software his whole career. Probably most famous for creating the Nivo Slider.