Reflections on 2014

I’ve never been much for resolutions, per se, but I do think it can a good idea to reflect on the year that just passed before barreling headlong into a new one. In that spirit, I thought I would jot down a few professional milestones from the previous year.

Public speaking

One of my goals for the year was to try my hand at public speaking outside of the office. Fortunately, I had a couple of great opportunities. The first was WordCamp St. Louis where I spoke about responsive images (video | slides). The second was HighEdWeb Pittsburgh where I talked about some of the stuff I had been learning about designing mobile friendly web forms (slides).

In doing so, I was again reminded that one of the things I love most about the web industry is that it exists because people simply share what they know with the community. This year I hope to do even more sharing, even when—perhaps particularly when—I don’t feel like I have anything to share that would be of any value to others. I also met some great people who inspire me to be better at my craft and from whom I continually learn new things. Special thanks to Dave Olsen and Aaron Graham for giving me the opportunities at both events.

Learning new skills

My job title says “designer” but I’ve always been a design/development fence-sitter, because I like to be able to execute the ideas that I have in my head and not just make pretty photoshop comps describing what it is I want to see made.

This year, I decided I needed to bone up on my JavaScript skills a bit and found the JavaScript course at Codecademy to be a fun way to get back to the fundamentals and fill in some of the gaps in my knowledge from being a self taught hack. I can honestly say going through that course made me a better all-around programmer, not just when writing JavaScript, but also with the PHP that I was writing for WordPress projects.

Launching new projects

Working at a University comes with the chance to work on some really interesting projects. One such project came this year in the form of an ambitious proposal to launch a new online publication that would showcase original essays and reviews focused on the big ideas of our time.

Screenshot of the Common Reader homepage

After a lot of hard work with a great team of people, The Common Reader was launched in October. I was the primary designer and did quite a bit of development on the site, which was a lot of fun. I look forward to watching the publication blossom and grow in the coming years.

Contributing to WordPress core

I’ve used WordPress longer than Facebook has been a company, but had never even thought about contributing any code to core until earlier this year when I ran across a bug on a project at work and decided to learn how to submit a patch. Once I saw, ‘props joemcgill,’ show up in the Trac logs, I was hooked. I ended up working on several patches, some of which made it into the WordPress 4.1 release in December—a particularly fun accomplishment that would not have been possible without the support of the generous community that is behind WordPress development. I look forward to getting more involved in the WordPress community in the coming year.

A local WordPress setup using VVV

Varying Vagrant Vagrants (VVV) is an open source project based on Vagrant which helps you set up a local development environment preconfigured with everything you need to start doing WordPress development on a modern LEMP stack that mimics the configuration of several popular hosting environments.

Follow the setup instructions on the project’s Github page to get everything setup, which includes installations of the latest stable and bleeding edge versions of WordPress, and a development setup for working on WordPress core. After you’ve completed the installation process you can administer your environment through the command line, or if you’re on a Mac, use Vagrant Manager to control VVV directly from the menu bar.

An updated dashboard

VVV comes with a very basic dashboard to get started, which can be found by pointing your browser to The default dashboard gives you quick access to the essentials, but not much more.

For a better dashboard experience, including easy access to any of additional sites you may have set up, I recommend using VVV-Dashboard by Jeff Behnke.

VVV dashboard, v0.1.3.
VVV dashboard, v0.1.3.

Install it by cloning the repository into your vvv/www/ directory and copying dashboard-custom.php and style.css into your vvv/www/default/ directory.

Setting up additional sites on VVV

One of the great features of VVV is the auto site setup which can be used to create a new development site by modifying a couple of config files. Simon Wheatley has a nice example. I also recently ran across Alison Barrett’s terrific vvv-site-wizard, which automates the whole process of setting up new sites from the command line and even allows you to mirror the media directory of a live site, which comes in really handy.

By using VVV to get a local development environment in place, you can stop worrying about complicated server administration tasks and focus your attention on that next great WordPress project you’ve been thinking about.

Setting Up WordPress on DigitalOcean

I’ve recently had the need to explore a few different hosting environments and decided to give DigitalOcean a spin. Here’s a quick look at the steps involved in getting WordPress set up on a LEMP Ubuntu 14.04 droplet.

Setting up the Droplet

The initial setup was pretty easy after signing up for a Digital Ocean account. I chose the basic, $5/mo plan to get started and chose the LEMP on 14.04 image from the list of Applications.

DigitalOcean Image Options
DigitalOcean Image Options

The droplet took about a minute to spin up and then I logged in via SSH to complete the setup.

Setting Up MySQL

Before installing WordPress, you’ll need to create a new database and a new user with privileges to that database. When you first log in to the droplet via SSH, your root MySQL password will be displayed as part of the welcome banner. You’ll need that password to login to MySQL, using the following command:

mysql -u root -p

After logging in, you will create a new database like this:


Next, create a user with access to that database. First, create the user:

CREATE USER 'username'@'localhost' IDENTIFIED BY 'password';

Then, grant privileges on your database to the user you just created like this:

GRANT ALL PRIVILEGES ON dbname.* TO 'username'@'localhost';

And finally, reload privileges by running:


Create a non-root user

I like to log in using a non-root user to administer the server. The process I followed can generally be found here: starting at step 3.

Add a new user by typing the following command:

adduser username

Follow the prompts to set the username and additional info.

Add sudo privileges for the new user using


Look for the line that looks like this:

# User privilege specification

And add the following just below:

username ALL=(ALL:ALL) ALL

I like to be able to log in without putting in a password, so I copy the contents of my public key (~/.ssh/ from my computer into a the authorized_keys file (~/.ssh/authorized_keys) in the user directory of the new user I just created on the droplet.

If everything went well, I should be able to log into the droplet from my terminal by typing a command that looks much like the following:


Installing WP-CLI

I love the power of managing WordPress from the command line using WP-CLI. I follow the installation process on their website to get up and running.

curl -O

The next step they suggest is making sure it works by typing

php wp-cli.phar --info

At which point, I got an error about needing to have php-cli installed. To fix this, I ran the following:

sudo apt-get install php-cli

Once php-cli was installed, WP-CLI worked like a charm and I completed the setup suggested at by making the file executable and moving it into the executable path like so:

chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp

Installing WordPress

Now that WP-CLI was installed, I created a new directory at /var/www/ for all of my sites and used WP-CLI to download WP into a new directory for my first site.

wp core download

Next, cd into the new directory and create a wp-config.php file. I use wp-cli for this too, using the mysql database name and user we created earlier.

wp core config --dbname=dbname --dbuser=username --dbpass=password --dbhost=localhost

You can even use WP-CLI to install wordpress and setup your admin user.

wp core install --title=My Site Title --admin_user=username --admin_password=password

That’s it. Now you have WordPress installed. The next step is setting up Nginx to serve up the site we just created.

Setting Up Nginx

Nginx (pronounced like engine ex) is a powerful—and generally faster—alternative to using Apache as your web sever. All the cool kids are using it and so should you.

To configure Nginx to serve our freshly installed WordPress site, follow these directions.

I’ll break it down.

First, create the config file for our site by copying the default config:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/

Open your new config file and make the following edits:



location / {
try_files $uri $uri/ /index.php?q=$uri&$args;

Next, we need to enable to site. The easiest way to do this is by making a link to our config file in the /etc/nginx/sites-enabled directory and remove the default:

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

sudo rm /etc/nginx/sites-enabled/default

Finally, restart Nginx and PHP

sudo service nginx restart
sudo service php5-fpm restart

Finishing Up

Once you’ve completed these steps, you should be able to point the DNS for your domain (e.g. or set up a hosts file entry that points at the IP address for your droplet. If all is well, you should see your new site served when you visit from your browser.

There are a couple of additional packages I would suggest installing before finishing up.

WordPress uses postfix to send out emails (e.g., password reminders, notifications, etc.). I use apt-get to install postfix, following these instructions to complete the process.

I would also suggest installing an opcode cache. I chose APC:

sudo apt-get install php-apc

More on my caching setup in a future post.