A dependency manager is one of those magical tools, like a smartphone, that most people (myself included) didn’t know they needed until they tried it, but once they did, they were hooked.
A dependency manager wrangles together all of the different pieces that go into a plugin or theme — such as frameworks, JavaScript libraries, jQuery plugins, or even the plugins, themes, and libraries that makes up a WordPress site.
There are lots of dependency managers out there, but the standard for PHP development is Composer. Composer is user friendly and works great with WordPress.
Keep in mind that one of the things that WordPress does is dependency management, and that may be enough for you. A WordPress site is a combination of WordPress core, which is managed via the core updater, and a collection of themes, plugins, mu-plugins, and drop-ins that are managed via the theme/plugin manager and updater.
In some cases that’s enough, but for theme and plugin development, or for sites with lots of moving pieces, Composer can be a real frustration saver.
Many people use Git or some other version control system for what a dependency manager, such as composer, should be used for. They have one Git repository for all of their code — both code they are writing and code other people are writing. It also leads to mixing multiple parts of the code you are writing in one repository. Composer actually makes working with multiple repositories easier.
Composer allows you to have multiple repositories with the theme and plugins your developing for a site, along with the code you’re using managed from one central location. You update all of your dependencies with one command:
composer update
When and Where to Use Composer
There are three separate situations where you may want to use composer to manage dependencies in WordPress:
- To manage dependencies for a theme or a plugin you’re developing
- To manage your themes and plugins used on a site
- For total site dependency management
Each of these situations has its own needs, for dependency management, as well as pros and cons for using Composer. For example if you’re developing a site or a WordPress-powered app, you have more options for choosing dependent libraries than when making a plugin or theme for release. So let’s address each of these potential uses individually.
The first case is when you’re developing a theme or plugin for public release. Themes and plugins are often reliant on third party JavaScript or SASS/LESS libraries. Composer really does a great job keeping these up to date, as opposed to managing them via Git Submodules, or via cut and paste.
This does, however, get tricky as your dependencies for a theme or plugin may include libraries bundled with WordPress or other plugins, which in this situation, Composer is not great for managing.
On the other hand, Composer is great for keeping a framework like Bootstrap or Foundation updated in your theme, or managing jQuery plugins used in your WordPress plugin.
If you are developing a full site or WordPress powered app, this means you control all of the code on your site, and you have more flexibility than when writing code that might be used by others. Using Composer allows you to break your code into multiple version control repositories, which maximizes code reusability, and manages and updates them from a single location.
Whether Composer manages just your content directory or the entire site, it’s an important decision to make. If done right, you can use Composer to manage the entire site, and have the site’s Git Repo just contain wp-config.php — a index.php and the composer.json file.
A simple example of this can be found in Simeon Wheatley’s VVV demo configuration. The actual Git repository just creates the structure. Then Composer is used to fill in WordPress and the plugins and themes. You can use a setup to move between local development and a live server, with relative ease. On the live server, you would just clone the repo and then run composer update.
For a more complex setup that adds automated deployment, I recommend checking out Bedrock. Bedrock uses Capistrano to deploy from local to production, and in turn automates the process of running Composer on the live site.
A simpler, though less automated setup, would be to add a composer.json file in the root of your content directory and use it to install plugins and themes only.
One great thing about using Composer for managing dependencies for a full site is that it reduces redundancy. If you want to use one JavaScript library in two custom plugins, you can do so with confidence that managing and updating that library will be easy and installed in a consistent location.
In order to use Composer, you must have it installed on your server and/or development machine. The need to have it on your server might not be valid if you’re using Composer for theme/plugin development. In addition, you need a valid composer.json file.
Installing Composer
Composer needs to be installed via the command line, but this is very easy to do on your computer or server. To install Composer globally, which enables using the composer command in any directory with a valid composer.json, you only need two simple commands:
curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer
This assumes your computer has curl installed, which it should. Also keep in mind that you must have command line access to your server, which is not something that all WordPress hosts support. If your host does not give you this access, you will have to run composer locally and push your changes via sFTP or some other method.
Writing a Composer File
The composer.json file defines what files Composer will get for you. These may be plugins, themes, libraries frameworks, or even WordPress itself. In addition, it lists some information about the project.
The dependencies must be from either a Packagist server, in a version controlled repository with a valid composer.json of their own, or point to a zip file. A Packagist server is a repository for Composer packages. The main Packagist server is Packagist.org, but as a WordPress developer, you may be more intrested in WPackagist.org, which is a mirror of the WordPress.org theme and plugin repositories as composer packages, which is awesome. I’ll show you how to use both shortly.
Here is an example composer.json file for a plugin:
{ "name" : "vendor/plugin-name", "description" : "Automatic front-end output of Pods Templates.", "type" : "wordpress-plugin", "keywords" : [ "wordpress" ], "license" : "GPL-2.0+", "authors" : [ { "name" : "Developer Name", "email" : "[email protected]", "role" : "Lead Developer" }, { "name" : "Developer Name", "email" : "[email protected]", "role" : "Developer" }, ], "require" : { "composer/installers" : "~1.0.0", "php" : ">=5.2.4", "twbs/bootstrap" : "3.2" }, "extra" : { "installer-name" : "plugin-name" }, "homepage" : "http://plugin-name.com", "support": { "issues": "https://github.com/vendor/plugin-name/issues", "source": "https://github.com/vendor/plugin-name/pods-frontier-auto-template" } }
You’ll notice that most of this is information about the plugin — such as who made it, what it does, where to report issues, etc.
The two most important things to notice are the “require” section and the “type” section. While it’s not formalized, there is an effective standard that WordPress plugins use the type “wordpress-plugin” and themes use the type “wordpress-theme.” The type is important, as when we look at the Composer file for site management we’ll see we can specify a custom path for installing plugins and themes.
In the “requires” section, we list the requirements for this project. You’ll notice the line:
"twbs/bootstrap" : "3.2"
That’s an example of how to add a third-party dependency from Packagist.org, in this case Bootstrap. I’ve listed a specific version of Bootstrap, but you can get the latest version by setting the version number to “*.” This will install Bootstrap in a folder called “vendor” in your plugin.
You can change the name or path of that default vendor directory by adding a “vendor-dir” declaration to the config section of your Composer file, like this:
"config" : { "vendor-dir": "libraries" },
Alternatively, if you’re using Composer to manage your entire site, you will want to list all of your plugins and themes, and define a path for where to install them. As I said before, there is a packagist mirror of the WordPress.org theme and plugin repository at WPackagist.org. This means that we can add any plugin or theme using wpackagist-plugin/plugin-slug or wpackagist-theme/theme-slug. For the plugin or theme slug you use the page slug of the theme or plugin’s page on WordPress.org.
Here is an example composer.json for a full WordPress site, that manages plugins, themes, and WordPress itself:
{ "name" : "vendor/project", "description" : "Site build stack.", "keywords" : [ "wordpress" ], "license" : "GPL-2.0+", "authors" : [ { "name" : "Developer Name", "email" : "[email protected]", "role" : "Lead Developer" }, { "name" : "Developer Name", "email" : "[email protected]", "role" : "Developer" }, ], "type" : "project", "minimum-stability": "dev", "repositories": [ { "type": "composer", "url" : "http://wpackagist.org" }, { "type": "git", "url": "https://github.com/pods-framework/pods-json-api" } ], "config" : { "vendor-dir": "vendor" }, "require" : { "johnpbloch/wordpress" : "4.0", "wpackagist-plugin/pods" : "*", "wpackagist-plugin/json-rest-api" : "*", "json-rest-api" : "*", "wpackagist-plugin/log-viewer" : "*", "wpackagist-plugin/caldera-forms" : "*" }, "require-dev" : { "wpackagist-plugin/log-deprecated-notices" : "*", "wpackagist-plugin/debug-bar" : "*", "wpackagist-plugin/debug-bar-console" : "*", "wpackagist-plugin/user-switching" : "*", "wpackagist-plugin/simply-show-ids" : "*" }, "extra" : { "wordpress-install-dir": "public_html/wp", "installer-paths": { "public_html/content/plugins/{$name}/" : ["type:wordpress-plugin"], "public_html/conent/{$name}/" : ["type:wordpress-theme"] }, } }
Some of this is similar to the last example, but some is very different. Let’s walk through the important parts.
First, notice that in the repositories section is a link to a Git repository. This is necessary, as this particular plugin is not available via Packagist or WPackagist. As a result, we need to tell Composer to treat it as a Git repository and provide it with the path to GitHub repository that the plugin is in.
This is an incredibly powerful feature of Composer, as the GitHub repository could be private, but as long as the computer that you run has access to the repository (i.e., you’ve added its public SSH key to your GitHub or other Git hosting account), Composer can install it.
The next thing to notice is that we have two separate require sections, the second of which will only be used in development. That’s full of useful development plugins that you wouldn’t want running on your live server.
You probably noticed that the first line of the require section is installing WordPress itself. While there is no official WordPress package on Packagist, John Bloch‘s package is a reliable source for all versions of WordPress.
Make sure to pay extra attention to the “extra” section at the very end, which defines custom paths for WordPress itself and WordPress plugins and themes. Without this, all repositories would go in the vendor file, which is not useful.
The first line of this section defines a path for installing WordPress, which in this case is public_html/wp. Make sure to customize this and the value of ABSPATH to fit your needs. The next two lines tell composer where to install plugins and themes. Again, make sure you match these to your install directory and the value of WP_CONTENT_DIR and WP_CONTENT_URL. You probably saw that those paths include a variable {$name}. That matches the value of “installer-name” that we saw in the example plugin composer.json earlier. When installing from WPackagist, that will be the plugin or theme’s slug.
Waving the Baton
I hope this introduction to Composer has helped highlight some of the amazing capabilities of Composer and how it can improve your development workflow. I haven’t even covered its autoloader, or how to integrate it with Grunt to automate the build and/or deploy process.
There are lots of great resources out there for learning about using Composer with WordPress. Andrey “Rarst” Savchenko curates a collection of resources on using Composer with WordPress. I also recommend checking out David Smith’s article on using Composer as the cornerstone of team-based WordPress development.
If you have any tricks for using composer to improve your WordPress development workflow, or have other resources to recommend, please share them in the comments below!
9 Comments