Updated 02.18.2015

How to install WordPress Plugins with Composer

What happens when you’re working with another WordPress developer, both developing a site locally, and someone updates the plugins on their local version? Their syntax and implementation may be different than yours if it was a major release. Suddenly, your local copy is broken. No fault of your own, just inconsistencies within the project.

What do you do? How do you prevent that from happening?

Let me present another scenario. Maybe this one will hit a little closer to home. Everytime you set up a WordPress site, you have to go through the same motions of downloading, installing, and activating a set of plugins. Maybe you’ve upped the ante a little bit and have a set of files on your local machine you just copy and paste everything over. Regardless, it’s still a pain when those plugins are updated. You have to visit each individual site, download the revised plugin code and replace the existing copy on your hard drive.

There must be an easier way…and there is!


I’ve started using Composer in my workflow, now most of those headaches have evaporated.

First things first

Let’s get Composer on your machine (COUGH Mac).

If you visit Composer’s site, it will explain your options in more detail. My preference, though, was to install it globally so that the composer command can be run anywhere on your system.

Open the Terminal and from the command line, run:

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


If the above fails due to permissions, run the mv line again with sudo.

On to the fun part…

Within your WordPress project directory, create a file called composer.json.

Wordpress Project Structure

As the extension suggests, this is a preference file, written in json that describes the plugins you’ll be installing and their version numbers.

Here’s my broilerplate. Feel free to copy it and use it as a stating point for your own projects.

Let me walk through it line by line.

The first few lines are pretty obvious. Name is the name of your project. You can replace ahaywood/PROJECTNAME with your information. Ideally, this should reflect your repo name.

Under authors, you can change “Amy (Haywood) Dutton” and “email” to include your name and email address respectively.

I’m going to jump down to line 27, where it reads extras. This defines the paths for both plugins and themes. As you can tell, I have a wp-content folder within the root that includes sub directories for plugins and themes.

On line 33, I’ve listed all the plugins that the project requires.

WP Packegist makes this easy. They mirror all the WordPress plugin and theme directories as Composer repositories.

What does that mean?

If you got to WordPress.org and find a plugin you want to implement, you can also find it on WP Packegist.

Take the first plugin I have listed: Backup WordPress. The part of the URL that comes after /plugin is the name of the WP Packegist repo.

Backup WordPress on WordPress.org

If you’re still not exactly sure what the name of the repo is, WP Packegist just implemented a search on their site. (Quick Note: I searched for “Backup WordPress,” first, and it did not return any results. But, searching for “backupwordpress” returned what I was looking for.)

Backup WordPress on  WP Packegist

Line 34 includes the full name of the repository: “wpackagist-plugin/backupwordpress”.


You can also see there are several other plugins from Wp Packegist that I’m referencing:

"wpackagist-plugin/backupwordpress" : "3.0.*",
"wpackagist-plugin/intuitive-custom-post-order" : "2.1.*",
"wpackagist-plugin/wordpress-seo" : "1.7.*",
"wpackagist-plugin/wp-help" : "1.3.*",
"wpackagist-plugin/user-admin-simplifier" : "0.6.*"

See the Pen Highlight WPackgist by Amy Dutton (@ahaywood) on CodePen.

The number following the name is the version number. The star serves as a wildcard. This means for Backup WordPress, versions 3.0.1 or 3.0.4 would both qualify. You also have the option of being explicit when you define the version number:

"wpackagist-plugin/backupwordpress" : “3.0.4”


Just checking to see if you’re paying attention here. One of the cases I made for Composer was that it would lock down your plugin files. How does that work with wildcards and version numbers, obviously 3.0.1 and 3.0.4 are not the same. — For now you can just trust me or if it’s really bothering, skip down to the section where I talk about the composer.lock file.

The only reason that Composer knows to look at WP Packegist for these packages, is because it’s defined as a reference on line 11 and 12.

"type" : "composer",
"url"  : "http://wpackagist.org"

See the Pen Reference Wpackagist by Amy Dutton (@ahaywood) on CodePen.

Setting up a Premium WordPress Plugin (or a plugin on a private repository)

You’ll notice several other repositories are referenced on lines 14 – 25:

     "type" : "vcs",
     "url" : "[email protected]:ahhacreative/ahha<em>plugin</em>acf.git"
     "type" : "vcs",
     "url" : "[email protected]:ahaywood/ahha-gravityforms.git"
     "type" : "vcs",
     "url" : "[email protected]:ahaywood/ahha-wp-db-migrate-pro.git"

See the Pen Reference Repositories by Amy Dutton (@ahaywood) on CodePen.

and implemented on lines 39 – 41:

"ahaywood/ahha-gravityforms" : "1.8.*",
"ahaywood/ahha-wp-db-migrate-pro" : "1.3.*",
"ahhacreative/ahha<em>plugin</em>acf" : "5.1.*"

See the Pen XJpeYw by Amy Dutton (@ahaywood) on CodePen.

The reason these are different is because they are premium plugins and unavailable on WordPress.org. I still want to use Composer, though, so I’m hosting them in private GitHub and BitBucket repositories

First, I tell Composer what type of files they are (vcs) and where they are located (url).

     "type" : "vcs",
     "url" : "[email protected]:ahaywood/ahha-gravityforms.git"

See the Pen EaZwRq by Amy Dutton (@ahaywood) on CodePen.


The URL is the SSH address, NOT HTTPS.

Then, I reference them as project requirements:

"ahaywood/ahha-gravityforms" : "1.8.*",

That takes care of our composer.json file. Woo hoo

Now let’s talk about actually getting that plugin set up correctly on your BitBucket, GitHub, Beanstalk, or whatever account.

Here’s what I do: Download the plugin code. Create a folder on my computer where this code can live. I actually have a folder called COMPOSER for this exact purpose.

Composer Files in Finder

Within the plugin folder, create a composer.json file

Screen Shot 2015-01-08 at 9.13.24 PM

This file is a lot smaller than before:

  • name is the name of the repository
  • type is the type of file it is. — It could be “wordpress-plugin” or “wordpress-theme”. (Remember, when we talked about installer-paths in our first composer.json file? We defined the install paths for both a wordpress-plugin or wordpress-theme. Line 29 and 30. It actually looks at this line to know what the type of file it is and to make sure it gets installed in the right place.)
  • require this line refers tothe version of composer we’re running, NOT the version of the plugin. (Can you tell I’ve gotten that mixed up before?)

Add this folder as a local repository. My app of choice is Tower.

Add a Local Repo in Tower

Run an initial commit.

Then, create a remote repository and link it to your repository.

Adding a remote repository in Tower

Now, you’ll also need to create a tag for your commit. This relates to the version number you’re referencing in your composer.json file. I like for my numbers to match the develpers’ release numbers.

In Tower, you can click on the branch, then right click on a particular commit. Select “Create New Tag from…” in the drop down menu.

Adding a tag within Tower

In GitHub, tags are referred to as releases. So, if you’d prefer to do it from their site, you can click on the Releases tab, then Draft a new release.

Release inside GitHub
Draft a New Release inside GitHub

Updating your plugin

When you get ready to update the plugin, simply download the latest release from the developers’ site, then replace all of the code in your local repository with theirs.

Commit it, tag it, and push it to your remote repository.


Let’s download all these plugins and actually install them on WordPress.

Within the root of your project folder, inside the Terminal, run composer install.

Run composer install from Terminal

It might take a while, but when it’s done, you can go to the Plugin screen of WordPress and activate all your plugins.


If you get an error within the Terminal about not having the right privileges to download the plugins, it’s probably related to your SSH keys.

I actually wrote a blog post about Setting up a Site with SSH. I can’t tell you how many times I actually reference that post myself! The post refers to SpringLoops, but the same applies here. Scroll down to where it says, “First, you’ll need to check for existing SSH keys.” Once you copy the keys to your clipboard, you can go to your service of choice, find the section that says SSH keys, and paste them there.

SSH Keys within GitHub
SSH Keys within BitBucket

Update January 26, 2015

I just moved all my Composer plugins off of GitHub to BitBucket. I had some problems. I kept getting an error everytime I ran composer update:


I was finally able to get it to work, but I had to change the version number within my main composer.json file to dev-master. In context:

"require": {
     "ahhacreative/ahha_plugin_gravityforms" : "dev-master",
     "ahhacreative/ahha_plugin_wpdbmigratepro" : "dev-master"

Then, within each individual plugin’s composer.json, I had to add a version and dist parameter:

  "name": "ahhacreative/ahha_plugin_wpdbmigratepro",
  "version": "master",
  "type": "wordpress-plugin",
  "require": {
    "composer/installers": "v1.0.6"
  "dist": {
        "url": "[email protected]:ahhacreative/ahha_plugin_wpdbmigratepro.git",
        "type": "git"

Update February 18, 2015

I just ran into an issue when I was trying to deploy my site via capistrano: No submodule mapping found in .gitmodules for path.

No Submodule Mapping Found

Fortunately, this article pointed me in the right direction. Within my root directory, there’s a file called .gitmodules, I opened it up and all that was listed was the WordPress submodule:

[submodule "wp"]
	path = wp
	url = git://github.com/WordPress/WordPress.git

I added the following lines:

[submodule "ahha_plugin_acf"]
 	path = wp-content/plugins/ahha_plugin_acf
 	url = [email protected]:ahhacreative/ahha_plugin_acf.git
[submodule "ahha_plugin_gravityforms"]
 	path = wp-content/plugins/ahha_plugin_gravityforms
 	url = [email protected]:ahhacreative/ahha_plugin_gravityforms.git
[submodule "ahha_plugin_wpdbmigratepro"]
 	path = wp-content/plugins/ahha_plugin_wpdbmigratepro
 	url = [email protected]:ahhacreative/ahha_plugin_wpdbmigratepro.git

Problem solved.


You’ll also notice that now, in addition to your composer.json file, there should be a composer.lock file. This file locks things down. It records the exact version of the file being installed.

If you want to update your site, simply go to the composer.json file, update the version numbers and then go to your project folder, inside the Terminal, and run composer update. Yep! That simple.

This seems awfully complicated…

Like a lot of things in the dev world, it can be a lot up front. That’s the learning curve talking. But, once that’s mastered, things go a whole lot faster. So, here’s my process now:

  1. Create a WordPress project using Yeoman.
  2. Within the root folder, create a composer.json file, copying and pasting my own GitHub boilerplate gist.
  3. Go to my project in the Terminal and type cu (I have Oh My Zsh! installed with the composer plugin activated.)

That’s it! 3 steps!

Posted 11.25.2009

Updated 02.28.2015

Writing jQuery Plugins (Part 1)

The more I write code, the more I realize how repetitive it is. It’s more cost effective (and brain-thawing), if you can figure out ways to be reuse your code. A few weeks ago, I started trying to figure out how to write my own jQuery plugins. Granted, you can probably find an existing plugin for anything that catches your fancy, however, a lot of times, the footprints are larger than necessary to accommodate more people. Besides, I’ll usually find one effect and stick to it (personal preference), rendering most of the customization in the plugin useless. At this point, it becomes easier to write my own code.


Here are a few sites that I looked at to help me get a grasp on structure. As most things, some are better than others. The hard part is some people assume you know more or less, leaving you to put the pieces together. My goal, in this post, is to the heavy lifting for you.

First things First

I’m gonna assume that you’ve at least heard of jQuery. If not, the elevator pitch? It’s a framework for JavaScript. In my humble opinion, it’s far easier to understand and much easier to write than JavaScript. If you’re a web developer, it’s definitely something worth checking out. I’d start by visiting the jQuery site or I’ve listed a few books (yes, you read that correctly, books) at the bottom of this post.

Captain Obvious

The first thing you’ll need to do is download the jQuery library. This has to be included on your page before any jQuery code can be written.

<script src="js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script> 

Update February 28, 2015

One of the things I prefer to do is use Google’s CDN version of jQuery. Several reasons:

  • It prevents me from having to download the code and store it on my server.
  • If your user has visited another site that is using Google’s CDN version of jQuery, then their computer will cache the code on their computer. Then, when that same user visits your site, the code is already cached and it’s one less thing they will need to download to get your site to load.

Instead of using the above line, you can use this instead:

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

Digging In

File Naming Structure

Your file should always be called jquery.your_plugin_name.js. Obviously, your_plugin_name will be unique to your plugin.


Yes, documenting your code is a pain. However, I promise, when you come back to your code, months later, it more than pays off. The code that you say (and wish) you will never come back to will inevitably haunt you. (can you hear the agony of experience in my voice?) :-) Besides, plugins are meant to be reused.

At the top of my file, I list out the name of the plugin, the date that I wrote it, the author (me!), my url, requirements, and implementation.

/* ==================================================================
*    DATE:                 FEBRUARY 28, 2015
*    AUTHOR:             AMY HAYWOOD
*     URL:                 WWW.AMYHAYWOOD.COM
*    REQUIREMENTS:         jQuery
*                        Be sure to include the jQuery library before including this script
*        Within the $(document).ready(); all that you really need to include is:
*        |    $('.CLASS_NAME_FOR_ROLLOVER').rollover();
*        Within your HTML, be sure to give the image, use the same classname that you used to call .rollover()
*        Within the rel attribute, include the path to the rollover image
*        |    
===================================================================== */

Code within your plugin

Basically, every plugin that you will write, will have the following code in it.

(function($) {
    $.fn.rollover = function(options){
        var defaults = {};

        var settings = $.extend(defaults, options);

        return this.each(function() {


Let’s take a step back…



  • I want to have an image with the file path of the rollover in the rel attribute.
  • When the user rolls over the image, it is swapped out with the value provided in the rel attribute.
  • When the user rolls off the image, it is swapped back to the original image.

Easy enough?


If I didn’t plan on using this code again, I would simply put the following code in the $(document).ready(); code in my header.

$(document).ready(function() {
    $('img[rel]').each(function() {
        var curImg = $(this);
        // GET THE VALUES
        var defaultImage = $(curImg).attr('src');
        var rolloverImage = $(curImg).attr('rel');
        $(curImg).hover(function() {
            $(curImg).attr('src', defaultImage);
        }, function() {
            $(curImg).attr('src', rolloverImage);

Too much too fast? No worries. I’ll break it down.

When you write jQuery code, most of it will appear within $(document).ready();. Basically, it waits until all the pieces on your web page have loaded and are available.

In this example, if we tried to find all the images before they had even loaded, it would return nothing!

$('img[rel]'.each(function() { 

This line of code looks for every image with a rel attribute. For EACH item, it will grab the current image src $(curImg).attr(‘src’) and save it as defaultImage. Then, it will grab the path for the rollover image $(curImg).attr(‘rel’) and save that as rolloverImage.

Lastly, it will set up the behavior. The hover function takes two parameters. The first, will determine what happens when you rollover the item and the second parameter will determine what happens when you roll off. In this case, it’s just a matter of setting the img src based on the defaultImage and rolloverImage.


Basically, we take the code that we would have made for 1 site and plug it into our jQuery plugin structure. The hardest part is just making sure we abstract everything (a.k.a. make it generic enough so that we can use it over and over).

(function($) {
    $.fn.rollover = function(options){
        var defaults = {};

        var settings = $.extend(defaults, options);

        return this.each(function() {
            var $element = $(this);
            var defaultImage = $element.attr('src');

            $element.hover(function() {
                $element.attr('src',  $element.attr('rel'));
            }, function() {
                $element.attr('src', defaultImage);


The only thing that I changed was I took out the code that was in the .each() function (from my 1 site code) and placed it within the this.each(function() { }); of the plugin. Now, when I call the plugin, it will run the loop on all the items I pass to it.

So, in the header of my HTML file, it will look like this:

    <title>JQUERY ROLLOVER TEST</title>
    <script src="js/jquery-1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="js/jquery.rollovers.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript" charset="utf-8">
        $(document).ready(function () {
            // INITIALIZE PLUGIN

Now, for every item in the body that has a class name of .CLASS_NAME_FOR_ROLLOVER it will try and create a rollover.

Stay Tuned

This post would probably fit into the “assuming you know less” category. On Friday, I’ll take a more in depth look at plugins, demonstrating their extensibility (i.e. setting preferences). Just to whet your appetite, we’ll be building an image rotator where you can pass in the speed.

Download My Code

jquery.rollovers.js (kB)


Call me old fashioned, but I still enjoy reading programming books. I know, ancient. I love my Kindle, but there is still something to be said for flipping pages, laying out multiple books, and cross-referencing. With that said, my favorite jQuery resources are books. That’s how I taught myself.

Learning jQuery
This is the book that I used to teach myself jQuery.

jQuery Reference
This book is also published by Pakt Publishing. This is the book that I go to for reference.

jQuery in Action
Yes, the cover looks a little hokey, but some of the content in the appendixes is worth the book’s weight in gold.