My Current WordPress Workflow

I use WordPress for about 99% of my clients’ projects. I do this for a variety of reasons but mostly because my WordPress workflow is pretty efficient and my clients are already familiar with the administrative interface. One could argue that I need to branch out and use a better platform and someday I really plan to, but for the sake of the sanity of my clients’ and myself I’m keeping to what I’m good at.

There’s always the argument of whether WordPress is a real CMS or just a blogging platform. I personally think it’s a combination of both. Being open source you can make it whatever you want which is the beauty of it all. This post is more or less a documentation of my current process. Yes, there can be improvements to make things more efficient but what I’m doing now seems to be getting the job done way sooner than it used to.

If you would like to follow along with my workflow I created the “end” result of a typical starter theme after having optimized it based on what I’ve written in this post. Feel free to use it inside your own projects or modify it however you like. Click the button below to clone the repo.

Making Things Easier on Myself

Tools are without a doubt a god send to the web development community. My workflow uses a combination of the following:

I use these in combination to make my code more efficient as well as save time. Your own workflow will likely vary and that’s okay!

Downloading WordPress

You can download WordPress in a variety of ways. The age old method is to head to WordPress.org and click the Download button. This way works and is usually the route I take. Though sometimes, if I’m already inside iTerm2, I will just clone the repo from Github.

Creating a Database

database
MAMP comes bundled with phpMyAdmin. I tend to just use this to create a new database for WordPress to utilize. Sometimes I’ll use SequelPro for grins.

phpmyadmin

From within MAMP just head to the Databases tab and look for the form and label that says Create database. Enter a name, click create and you’re done.

Running WordPress locally

WordPress requires a database and a server running PHP to get things up and running. To support these requirements, I make use of MAMP to launch a local server on my Mac. MAMP stands for My Apache, MySQL, and PHP. You can run it on both Mac and PC.

Being more of a visual designer and developer I like and appreciate a GUI interface a bit more but that’s not to see I’m not scared of the command line.

A lot of developers would rather make use of something like Vagrant or VVV which is completely cool. I’ve tried them but found they weren’t for me (at least just not yet).

For fewer headaches, I find it easier to fire up MAMP and be ready to go. I have MAMP configured to serve websites out of a folder called _sites which lives inside my Dropbox root folder. I utilize Dropbox as a home for all my local sites for the sake of backups as well as utilizing multiple computers if I have to.

My workflow begins with creating a new folder that I usually name the same as the site I’m building and copy over the core WordPress download. Once inside the first thing I do is rename wp-config-sample.php to wp-config.php. I then change the user to password to root as so MAMP can make use of the site. I also pass in the same database name I created before.


// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', ‘mydatabase’);

/** MySQL database username */
define('DB_USER', 'root');

/** MySQL database password */
define('DB_PASSWORD', 'root');

If all goes well you should get a prompt for a new site installation by visiting the site in your browser using the localhost URL MAMP provides. Something like:
localhost:8888/mynewwebsite. From here I simply press forward and set up the site by going through the installation wizard WordPress provides.

Choosing a starter theme

When it comes to building a theme for WordPress there are a variety of platforms and themes to start with. I feel like I’ve tried them all but keep coming back to underscores.

As a starting point, I’m looking for a theme with very little opinionated code. Past starter themes I’ve tried come bundled with tons of extra markup, html classes, CSS, and junk I just don’t make use of. Even with the underscores theme I find myself deleting unnecessary code based on the project I’m working on at the time.

http://underscores.me/
http://underscores.me/

At underscores.me you can generate a new theme configured with the name of your choice. All functions will be based on your own naming conventions which is a huge perk for the sake of being a completely custom theme (which is what I tend to build).

There are advanced options to add if you click on the small “advanced options” link which include:

  • Theme Slug
  • Author
  • Author URI
  • Description
  • A SASS enabled option ( I usually check this box though never use the CSS bundled within as I like to start from scratch. Don’t ask me why…)

Custom themes vs. commercial themes

The themes I build tend to be “one-off” designs. They are made with specific intent so your mileage will vary if you try to mock my workflow at all. My utmost focus when choosing what to support in a given theme is to use the least about of resources possible. I do this to decrease page load times and any hiccups that may arise for the given dependencies of the project. Usually, the leaner and lighter a theme is the better it performs.

Many commercial theme builders have to provide insane amounts of support for various pages, functions, posts, styles, and more on a given theme. This means more code and more rendering times. I’m not down with that.

Configuring a theme

Out of the box, there are still a few configurations I do to the underscores starter theme before I begin on a project. These configurations usually apply to every project but not all of them.

1. Remove any and all CSS and start from scratch

I make use of Sass which is compiled by Gulp. When compiled this generates a new style.css file which WordPress requires in any given theme.

2. Initialize a git repo within the theme directory

Since I build my own themes by myself right now I can’t say I use git to the extreme, though I do make what I like to call “milestone commits”. These commits usually come about when I finish implementing support for a page or custom post type for example. It’s a nice way to be able to roll back if I have to even though it’s rare that I do.

Someday if I have a team under me I will make much more use of git and create new branches for new features that multiple people could contribute to.

For versioning I make use of Bitbucket right now because the private repos are free whereas with Github they are not.

You may be wondering why I use git inside the theme directory instead of the wp-content folder or even the whole site. I do this for a variety of reasons but mainly just for preference. I make use of WP Migrate Pro WordPress plugin to sync local or staging sites with production sites. The plugin has made my workflow incredibly more efficient and now I rarely need to worry about versioning everything inside the wp-content folder.

In a team setting, I would opt to initialize git inside the wp-content folder to keep any installed plugins in sync with all contributors. On my own, I tend to use different plugins on production sites that I just don’t need on my local sites. These include plugins that help with analytics, caching and more.

3. Run npm init

I use Gulp as a task runner inside my themes. Along with Gulp, I install various node packages that help me optimize files the way I like. Using Node and Gulp allow me to do the following:

  • Compile Sass into CSS and minify it
  • Concatenate JavaScript files into one, lint the code, and compile it into a single minified production file.
  • Optimize all images
  • Launch a port on my local server to reload the browser automatically after any change to my Sass or JavaScript files. This also creates an IP address of which I can share to people within my local network for review.

4.Create Gulpfile.js

Inside the Gulpfile.js is where all the magic happens. My current Gulpfile.js resembles the following:

"use strict";
var gulp = require('gulp'),
    sass = require('gulp-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    autoprefixer = require('gulp-autoprefixer'),
    newer = require('gulp-newer'),
    imagemin = require('gulp-imagemin'),
    browserSync = require('browser-sync').create(),
    reload = browserSync.reload,
    concat = require('gulp-concat'),
    uglify = require('gulp-uglify'),
    watch = require('gulp-watch');

var imgSrc = 'assets/images/originals/*';
var imgDest = 'assets/images/';

gulp.task('browser-sync', function() {
    browserSync.init({
        proxy: "localhost:8888/mysitename”
    });
});

gulp.task('sass', function () {
  return gulp.src('assets/sass/**/*.scss')
    .pipe(sourcemaps.init())
    .pipe(autoprefixer({ browsers: ['last 2 versions'], cascade: false }))
    .pipe(sass({ outputStyle:'compressed'}).on('error', sass.logError))
    .pipe(sourcemaps.write('./maps'))
    .pipe(gulp.dest('./'));
});


gulp.task('watch', function() {

    // Watch .scss files
    gulp.watch('assets/sass/*.scss', ['sass']).on("change", browserSync.reload);
    gulp.watch('assets/sass/**/*.scss', ['sass']).on("change", browserSync.reload);
    gulp.watch('assets/js/**/*.js', ['js']).on("change", browserSync.reload);
});

gulp.task('images', function() {
    return gulp.src(imgSrc, {base: 'assets/images/originals'})
        .pipe(newer(imgDest))
        .pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))
        .pipe(gulp.dest(imgDest));
});


var jsInput = { js: 'assets/js/dev/**/*.js' }
var jsOutput = 'assets/js/dist/';

gulp.task('js', function(){
  return gulp.src(jsInput.js)
    .pipe(concat('app.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./assets/js/dist/'))
});

gulp.task('default',['sass', 'browser-sync','watch','images', 'js']);

For this to run correctly I have to make a few new directories and do a bit of housekeeping to the starter theme.

First, you’ll notice the dependencies I require at the top of the file. These need to be installed using npm. (I keep a snippet of the packages below as it’s not easy to remember them all! On a side note, if you’re looking for a native snippets manager I highly suggest SnippetsLab. I prefer it over Atom personally.)

npm install gulp gulp-sass gulp-autoprefixer gulp-newer gulp-imagemin browser-sync gulp-concat gulp-uglify gulp-sourcemaps gulp-watch --save-dev

I head to my theme directory and run the above command inside iTerm2. After everything is installed all that’s left is deleting a few files from the starter theme and creating a few new directories.

I house all of my assets inside a folder called assets. This folder resembles the following structure:

assets-folder

Download the starter theme to see the entire structure.

By default, the underscores starter theme creates various directories outside of an assets folder like I created so I just delete those. I believe those files include the js directory and a few files and references in the inc folder depending on what I need to support for the theme I’m building. I move the contents of the js directory into my js/dist/ folder and update their paths inside functions.php.

Once all of the directories are created I can simply cd into my site’s theme directory using iTerm2 and then run gulp. If all goes as planned a new browser window will pop up and my new site is running at localhost:3000/mywebsite.

Important Note
Since I changed the place where my JavaScript files live I need to enqueue my production file inside of functions.php. Usually, before I forget I head there and add a line like the following code:

wp_enqueue_script( ‘mywebsite-app', get_template_directory_uri() . '/assets/js/dist/app.min.js', array(), '20151215', true );

Assessing the design

With my new theme finally optimized for development I move on to dissecting the design that needs to come to life. This often involves slicing out images or SVGs and establishing what kind of content I need to support the theme.

Anymore, I try to make use of SVGs for any sliced assets. I got my start designing websites inside of Photoshop since it was the way of the web design world for a while. Now that everything needs to scale due to the number of display widths and resolutions available, more and more attention is being put into SVGs since they can scale without losing any quality like raster images would do.

All this said, my workflow was way more efficient now that I switched to using Sketch for a lot of my design work. Sketch’s handy export feature makes my life so much easier when it comes to getting the graphics I need in the theme fast.

Most projects that I design for involve creating a style guide rather than a full high-fidelity design. If a client needs to approve the design before I begin coding (this is typically how I work), I will often design a few pages but definitely not EVERY page. This helps them visualize the direction and if they are on board. This also helps me land on a concept and later continue the concept with code.

styleguide
A new styleguide for a dentist I’m currently working on.

A style guide is where I usually begin in any given design these days. This helps me focus on color, tone, messaging, typography, interactive elements, and more.

The purpose of the style guide is to allow myself to author reusable elements in code so I don’t have to repeat code. Since I use Sass I create a lot of mixins which can be easily applied to elements in one line of code rather than writing many of the same lines over and over like traditional CSS. If you’re new to Sass I recommend reading an article I wrote about it and why I love it.

Optimizing Assets

Images
I make use of a Node package that optimizes images when I run gulp from the command line. Gulp looks inside my images directory and then inside an originals directory. When I place any images in the originals directory and run gulp the images get optimized. These optimized versions are moved to the main images directory for easy reference later.

SVG
I make a lot of use of SVGs though when exporting from Sketch there is often a lot of extra code within the SVG file I just don’t need. To fix this I use a tool called SVGO. This is another Node-based tool that you run from the command line. To optimize an SVG I would type

svgo /path/to/file.svg

The tool then works its magic and tells you how much file size it decreased the original SVG by. Pretty cool!

On top of using svgo, I often group my SVGs into a master sprite.svg file. This is useful for icons and other elements you may repeat around the site. There’s an entire article written on it that I mimic in my workflow. Since it already exists I suggest reading it as I follow the same pattern.

CSS/JS Minification
Since I’m already making use of Gulp in my project I often always minify both my CSS and JavaScript files. This in return serves basically unreadable code but that’s okay to me.

To help debug some styles I make use of Sass source maps. I already have this configured in my gulp file but it essentially tells me what Sass file a styled element is located in rather than the main style.css file. This is useful for finding exactly where a snippet of code lives if you make use of Sass partials like I do.

Plugins I Always Use

There are plugins for pretty much anything available for WordPress. For my own workflow, I tend to limit the use of plugins because that usually means more requests are being made in a given web page. Too many plugins can really degrade performance and let’s face it, some plugins out in the wild are just shitty.

Some of my essentials that really do improve my workflow include the following:

  • WP Migrate DB Pro – This is a premium plugin but its well worth the cost if you build a lot of WordPress websites. Trust me.
  • Advanced Custom Fields – There is a free version but the pro version again is well worth the cost if you build a lot of WordPress websites. I use this on almost every site I build to customize the backend so my clients aren’t calling me every hour to try and update something on their site.
  • Jetpack – JetPack is useful for a lot of enhancements. I will never use every feature under the hood but I do enjoy the extra features JetPack has to offer. From an authoring standpoint, the markdown feature is probably one of my favorites!
  • Yoast SEO – While at times this plugin is a pain in the ass it does help tremendously with SEO. If my clients need more SEO support this plugin does the trick.
  • Ninja Forms – I’ve only recently started using Ninja Forms but I really like it over most other form plugins. I typically used Wufoo in the past but got sick of having to update code directly each time a client wanted to update a form inside of Wufoo. To get full control of the form’s style I had to hard code it all which was a bummer.
  • WP Optimize – for production sites, I typically install this plugin to help with optimizing databases, revision amounts, and more. Not doing these optimizations really degrade a website’s performance.

Moving sites

After I get a site developed locally the next logical step is to launch it to a staging directory for my client’s review. To do this I make use of WP Migrate DB Pro. This plugin is the shit and I highly recommend it.

You literally log in to your remote site and your local site in two separate browser tabs, copy over a generated key, click a few options, and then migrate your site. You can push or pull and it’s amazingly efficient every time.

If I didn’t have this plugin I would be wasting tons of time messing with databases, SQL, and making backups manually. Yuck!

Maintenance and post launch

Recent versions of WordPress come with automatic updates which are a huge time saver. Unfortunately, plugins don’t have that luxury yet. My workflow often means this responsibility is a manual one that I have to do periodically for clients’ who have me manage their technical needs. I’m happy to do this for them but this step in my workflow could definitely be improved.

To fix this in the future I may opt to run managed WordPress installations through a new host but I’ll save that process and experience for another post!

Final Thoughts

Well, there you have it, my current WordPress workflow. Are there areas to improve upon? Always, but the more sites I build, the more ways I find better techniques to optimize my workflow a bit more. I think I have a habit of wanting to be in complete control of each step of the process so sometimes this makes my workflow less efficient. Maybe in the future, I’ll be more open to allowing more automation to take place perhaps? Either way, I’m excited to see how my workflow evolves!