Quiet desperation

This video resonated with my profoundly. So much so that I try to watch it back at least once a week.

As I’ve got older and life’s responsibilities have become greater, lifestyle creep has crept and things have become far more expensive, it’s become a lot harder to live a life that I used to dream of growing up. It’s harder to do and achieve the things that I set my heart on as a young man.

And so there are two paths that I can take at this point in time, the safe path or the dangerous path.

What ever you are doing, do it like your life depends on it.

Joe Rogan

Why I stopped writing

Almost 3 years ago I wrote an article that made me stop writing completely. I’ve never really told this story to anyone before.

Up until I published that article, I’d been writing weekly about WordPress development and industry related issues.

Since then I’ve posted 3 snippet type blog posts, but I stopped writing anything meaningful and the passion was gone.

The article that I wrote on that day got a ton of attention. It spread quickly through the WordPress community and was read by many peers.

Up until the point where I published that article, I was really confident in what I was writing.

I was publishing some interesting articles and many of them were somewhat controversial in that they drew some negative feedback from what I’d refer to as important people in the WordPress community. If you’ve been in WordPress development for even a short period of time, you’d know their names.

I was ok with it though.

I put on a hard face and defended my opinion in the best way possible. In some instances I had my mind and opinion changed through debate and discussion.

And then, that article.

I don’t know what it was about that article.

Maybe the chatroom that I found through my analytics were I was ridiculed by people I really respected.

Maybe the fact that they were trying to tear apart an open source project of mine because they didn’t like the article.

Maybe it was the one time commenters who leave negative comments and don’t come back to finish a discussion.

Maybe I was just tired of constantly having to deal with people trying to break me down.

And so I just stopped writing. I stopped sharing my opinions. I stopped exposing some of my insecurities and even naivety through my writing. Because the feedback was eventually too much to take.

I hear and have seen in some cases, that a lot of the development community works this way. Someone floats and idea through an article, pull request or tweet and if it’s not agreed with by some, the attacks start.

Instead of talking, showing empathy and teaching, names are called, expletives are used and people are broken down. It’s been said before, the anonymity that the internet provides brings out the very worst in people.

Inside, I feel even more vulnerable than before. It’s been a tough few years and I’ve lost a lot of confidence. I know though, the only way to grow stronger is to keep moving forward. To keep writing and sharing my ideas and thoughts.

And even though there are more trolls than before who want to break me down, I care a lot more about the many people who’ve emailed, Slacked, commented and shown appreciation for my writing and how it’s been valuable to them. They’re the reason why I’m back and I can’t wait to start sharing more.

2018 year in review

It’s hard for me to characterize the past year, in fact the past 3 years since it’s been that long since I did one of these updates. The start of 2016 started exceptionally well for me and up until speaking at WCEU 2016, things were really, really good.

Without getting into too much detail, that’s a story for another blog post, things culminated in a really difficult end of 2018. It was a tough year for me but there were a few highs worth noting. We’ll start with some of the lows though and end on a more positive note.

What didn’t go well in 2018

I didn’t blog or produce any video content. I went from an extreme content high in early 2016 to not doing anything since mid-2016. While this doesn’t sound like a big deal to many, producing content deeply satisfies me and fulfills what I believe to be a big part of my answer to the question that I continually seek to answer, “what I am here for?”.

Next, I took on side-projects and hustles that were not aligned to what I believe to be my true purpose in life. I need to constantly remind myself that I should not take on projects just to make a buck. I’ve learned that to be truly satisfied in my work, I have to be making a difference in peoples lives. These side-projects and hustles just added to the stress that I was already under.

Professionally, I don’t feel like I’ve grown much at all. I didn’t take opportunities that were up for grabs and I didn’t apply myself in areas that I wanted to grow in. I coasted along and while I worked hard, I didn’t work in the right areas.

And all the above led to an extreme bout of burnout towards the end of this year. After an extremely hectic project, I crashed. I’ve experienced burnt out before (see my 2015 update) and this time was just as difficult.

What went right in 2018

The highlight of my year professionally was leading the backend development of the RollingStone.com rebuild. There were some extremely challenging pieces to this rebuild and migration, but it all came through superbly in the end.

On a personal level, Megg and I bought a new house in Cape Town. Since moving to Cape Town in 2016, we had been renting until we found the right place to buy. In February, we signed an offer to purchase and we’re now living happily in our new home. Megg is also pregnant with our 3rd child! We’re expecting a baby girl in March. I’m still not convinced that Cape Town is our final destination, but it’s home for now.

Most importantly for my own wellbeing, I feel mostly recovered from the burnout. I’m so excited to start writing more in 2019 and producing YouTube tutorial videos again. I’m focused on aligning my work to what I call my True North or life calling and I’m ready to make 2019 my best year yet.

Some stats (for fun)

A year end review post is not complete without stats! Here’s some key metrics I like to measure – values in brackets are last years figures.

Blog stats

YouTube stats

  • Videos released – 0 (0)
  • Total views – 82100 (96600)
  • Minutes watched – 183900 (237700)

Subscriber stats

  • YouTube subscribers – 1580 (1284)
  • Email subscribers – 456 (417)
  • Twitter followers – 945 (?)
  • Facebook page likes – 224 (224)

Travel

  • Countries visited 2 (USA, Spain)

Moving forward in 2019

Overall, I suppose the past year (or years) can be characterized as a rollercoaster. I’m sure 2019 will bring it’s own set of challenges, but my hope is that by being true to what I believe to be my current purpose in life, I’ll do more meaningful work and be happier for it. Let the fun begin…

Add Custom Post Types to Zoninator

Zoninator is an simple plugin for being able to curate content on a WordPress website. While I personally feel that more can be done in WordPress when it comes to curation of content, Zoninator ticks most boxes of a simple to use and easy to implement curation solution.

By default, Zoninator only lets you select posts when selecting content for a specific zone that has been created. That’s all good and well, but what about when you want to select a piece of content that is filed under a Custom Post Type?

Turn’s out, you need to enable support for zoninator when registering the custom post type. To do that, simply add zoninator_zones to the supports argument when registering the Custom Post Type

Add Zoninator support when registering a Custom Post Type

Here is an example snippet of a Custom Post Type that is registered and includes support for Zoninator.

<?php
add_action( 'init', 'codex_book_init' );

/**
 * Register a book post type.
 *
 * @link http://codex.wordpress.org/Function_Reference/register_post_type
 */
function codex_book_init() {
	$labels = array(
		'name'               => _x( 'Books', 'post type general name', 'your-plugin-textdomain' ),
		'singular_name'      => _x( 'Book', 'post type singular name', 'your-plugin-textdomain' ),
		'menu_name'          => _x( 'Books', 'admin menu', 'your-plugin-textdomain' ),
		'name_admin_bar'     => _x( 'Book', 'add new on admin bar', 'your-plugin-textdomain' ),
		'add_new'            => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
		'add_new_item'       => __( 'Add New Book', 'your-plugin-textdomain' ),
		'new_item'           => __( 'New Book', 'your-plugin-textdomain' ),
		'edit_item'          => __( 'Edit Book', 'your-plugin-textdomain' ),
		'view_item'          => __( 'View Book', 'your-plugin-textdomain' ),
		'all_items'          => __( 'All Books', 'your-plugin-textdomain' ),
		'search_items'       => __( 'Search Books', 'your-plugin-textdomain' ),
		'parent_item_colon'  => __( 'Parent Books:', 'your-plugin-textdomain' ),
		'not_found'          => __( 'No books found.', 'your-plugin-textdomain' ),
		'not_found_in_trash' => __( 'No books found in Trash.', 'your-plugin-textdomain' )
	);

	$args = array(
		'labels'             => $labels,
                'description'        => __( 'Description.', 'your-plugin-textdomain' ),
		'public'             => true,
		'publicly_queryable' => true,
		'show_ui'            => true,
		'show_in_menu'       => true,
		'query_var'          => true,
		'rewrite'            => array( 'slug' => 'book' ),
		'capability_type'    => 'post',
		'has_archive'        => true,
		'hierarchical'       => false,
		'menu_position'      => null,
		'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments', 'zoninator_zones' )
	);

	register_post_type( 'book', $args );
}

Again, the specific piece to take note of is the supports argument. There is another method to enable support for Custom Post Types. If you did not register the Custom Post Type yourself or you don’t have control over it in your code, you can use the add_post_type_support function.

Alternative Zoninator add post type support method

Simply call the following function (just make sure it’s called after the post type is registered). It’s also a good idea to use an action to fire off the function.

<php
function mg_register_post_type_support() {
	// Zoninator on pages.
	add_post_type_support( 'page', 'zoninator_zones' );
}
add_action( 'after_setup_theme', 'mg_register_post_type_support' );

And there you have it. Two simple ways of adding Custom Post Type support for Zoninator.

Should you add actions or filters in your WordPress class constructor?

You may have heard that adding actions or filters to your WordPress class constructor is not a good idea when creating a theme or plugin. Yes?

Quick side note! Isn’t it annoying when someone mentions something isn’t a good idea, but doesn’t explain why? Yea I think so too.

So let me explain why and attempt to do it in a way that makes sense.

Essentially, there are two reasons why.

Why not to add actions and filters to your WordPress class constructor

  1. The role of the constructor
  2. Makes your unit testing, less unit-ty.

So first, the role of the constructor in PHP is to initialize your object’s properties. Everything else should be handled in the class methods. Is adding actions initializing the object? No it’s not since the actions (or filters for that matter), don’t do any initializing, they only hook in to WordPress and get called later during the WordPress execution.

Makes sense? No? Have a read of Carl Alexander’s article on plugin constructors – he has a knack of explaining things simply.

And the second reason, less unit-ty unit tests, probably isn’t so self explanatory. A unit test is meant to run in isolation and test the smallest unit of code. Most WordPress unit tests I’ve seen (and am guilty of writing) are actually more like integration tests as they test WordPress features and not class methods/units of code.

So if we’re writing pure unit tests, in the way they are intended to be written, and we add actions and filters to a constructor of a class in our plugin or theme, then we can’t test our code (or instantiate an object of a class), without WordPress and all the action/filters being applied. Yes, sometimes you may want them to be applied, but by only applying them in a separate method, you have the choice to load them if you want to by calling a method.

And if that didn’t make sense, check out Tom McFarlin’s article on the issue.

Now that all is said and done, I hope you have a better understanding of why you shouldn’t use actions and filters in your WordPress theme or plugin class constructors. Got questions? Hit me up in the comments below.

Display an Instagram feed on your WordPress website

Need to display an Instagram feed on your WordPress blog/site? Eaaassssyyy!

In this short little snippet, I’m going to show you how. I’ve done two different implementations of Instagram feeds on WordPress sites recently. The first one, was the display of a single users feed in the footer of a website. The second solution aggregated multiple different user feeds and showed the most recent images that were uploaded across the different feeds.

Today I’m going to share the first method, and then I will follow up this snippet with the aggregated solution in another snippet later this week.

Let’s dive in to the code first and then look at how it works…

WordPress Instagram Feed Snippet

<?php
/**
 * Class used for fetching and displaying Instagram feeds.
 *
 * License: GPLv2 or later
 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
 *
 * WordPress Instagram Feed Class, Copyright 2017 Matt Geri
 *
 * WordPress Instagram Feed Class is distributed under the terms
 * of the GNU GPL.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * @since 1.0
 * @package MattGeri
 */

namespace MattGeri;

/**
 * Class Instagram
 *
 * @since 1.0
 * @package MattGeri
 */
class Instagram {
	/**
	 * The transient key used to store the feed results.
	 *
	 * @since 1.0
	 */
	const TRANSIENT_KEY = 'instagram_feed_%s';

	/**
	 * When to expire the transient - set to an hour.
	 *
	 * @since 1.0
	 */
	const TRANSIENT_EXPIRE = 60 * 60 * 24;

	/**
	 * The Instagram endpoint for fetching images.
	 *
	 * @since 1.0
	 */
	const INSTAGRAM_API = 'https://www.instagram.com/%s/media';

	/**
	 * Display an unordered list of Instagram images for a given profile
	 *
	 * @since 0.1
	 * @param string $user The Instagram user id.
	 */
	public function display( $user ) {
		$instagram_feed = $this->fetch( $user );

		if ( ! is_wp_error( $instagram_feed ) && ! empty( $instagram_feed ) ) {
			?>
			<ul id="instagram">
				<?php foreach ( $instagram_feed as $image ) : ?>
					<li class="instagram-item">
						<a href="">
							<img src="" alt="" title="">
						</a>
					</li>
				<?php endforeach; ?>
			</ul>
			<?php
		} else {
			esc_html_e( 'There was an error retrieving the Instagram feed', 'instagram' );
		}
	}

	/**
	 * Fetch and cache an Instagram feed for a given profile.
	 *
	 * @since 0.1
	 * @param string $user The Instagram user id.
	 * @return array|\WP_Error
	 */
	public function fetch( $user ) {
		$instagram_api = sprintf( self::INSTAGRAM_API, $user );
		$transient_key = sprintf( self::TRANSIENT_KEY, $user );

		if ( false === ( $instagram_feed = get_transient( $transient_key ) ) ) {
			$instagram_feed = array();
			$response       = wp_remote_get( $instagram_api );

			if ( ! is_wp_error( $response ) ) {
				if ( 200 === wp_remote_retrieve_response_code( $response ) ) {
					$body = json_decode( wp_remote_retrieve_body( $response ) );

					if ( ! empty( $body->items ) ) {
						foreach ( $body->items as $image ) {
							$instagram_feed[ $image->created_time ] = array(
								'src'     => $image->images->standard_resolution->url,
								'link'    => $image->link,
								'caption' => $image->caption->text,
							);
						}
					}

					set_transient( $transient_key, $instagram_feed, self::TRANSIENT_EXPIRE );
				} else {
					return new \WP_Error( 'instagram_feed_failed', __( 'Failed to retrieve Instagram feed', 'instagram' ) );
				}
			} else {
				return $response;
			}
		}

		return $instagram_feed;
	}
}

$instagram = new Instagram();
$instagram->display( 'mattgeri' );

How The WordPress Instagram Feed Snippet Works

So! What’s happening in the above snippet?

Line 63: display is a public method that can be called on the class and it will fetch the feed (see line 64) and then output a unordered list (see line 68) of all the images that were returned from the feed.

Line 96: If you’ve got a keen eye, you’ll notice that I’m using a JSON feed that is provided by Instagram to fetch the images that have been uploaded by the user.

Line 112: We then cache the results inside a WordPress transient so that we don’t hit up the Instagram feed on every page load. We cache the results for a day (see line 48)

That’s pretty much it! If something goes wrong, a WP_Error is returned and we handle it gracefully on line 78. Feel free to play around with the class and make it even better! Send me a link once it’s done so that I can check it out.

Free WordPress Instagram Feed Plugin

So just because I can, I’m bundling up this snippet in to a free, open source plugin that you can download and install from the WordPress plugin repo. Check back in a couple days for the plugin URL.

Should WordPress developers be taken more seriously?

I recently wrote an article for SitePoint.com on the ultimate WordPress development environment. If you’ve been following me for a while you will know this is something I’ve spent a good deal of time figuring out.

What surprised me was the feedback that I got on the article.

Using the word “ultimate” in the title was definitely a little bit contentious, and I expected to have some readers push back on it. However, they didn’t. The feedback I got on the content of the article was quite positive.

Out of nowhere though, a number of people started critiquing me for implying that you could apply coding standards to WordPress. Reading deeper in to their thoughts, the crux of their argument seemed to be that they feel WordPress is architected really badly and inherently, anyone who works on WordPress must be a sub-par developer just because of their association with the platform.

That’s a very unfair judgment and from my experience, very far from the truth.

So why is that an unfair judgment?

To answer that question, we really need to look at one simple thing. Why do developers choose WordPress?

Why do developers work with WordPress?

I think we could all agree that there are architectural blemishes in Core, but good developers still choose to work with WordPress despite this. Here’s why.

  • Open source. That warm fuzzy feeling inside from contributing code to a greater cause.
  • Large share of the market. 25%, enough said!
  • Established platform. Large and small, old and new businesses are running on it (including some of the biggest brands).
  • Easily extendable. Actions and filters.
  • The business opportunity also can’t be ignored.

Because of all of this and more, WordPress has a thriving development community and it’s only getting bigger and better.

Are architectural hiccups in Core a good enough reason to ignore all of the platform benefits? Personally I don’t think so.

So the question then becomes, why should WordPress developers be taken seriously?

Why should WordPress developers be taken more seriously?

They should be taken more seriously, not because of the platform they choose to develop on, but for the skills that they demonstrate in their work. Skills like…

  • Working with bleeding edge frameworks and tools. The REST API has opened up opportunities for heavy JS development and apart from that, the tooling available for WordPress is on par with other communities like Ruby, Python and Go.
  • Writing well architected WordPress themes, plugins and applications. Plugins, themes and applications don’t have to be restricted by the architecture of Core. I’ve seen tons of really well architected plugins. Good WordPress developers do apply standards to their code and care about their craft.
  • Solving hard challenges. If you’re working with any semi-decent sized WordPress website there are challenges around scaling that need to be addressed. There are many other kinds of challenges around architecture, design, UI and more. Challenges make stronger developers.
  • Community spirit. You’ll find that many WordPress developers have a good sense of community spirit and this makes them great team players.

These skills are desirable of any developer. WordPress developers are no exception. And that is why WordPress developers should be taken more seriously.

 

Dealing with stressful development projects

At exactly 11:34am this morning I became temporarily homeless.

In January this year, my wife and I decided that it’s time to move our family from Pretoria to Cape Town, here in South Africa. And so we put our house on the market and it sold a lot quicker than we thought it would (in the first week of being for sale).

In South Africa it takes around 3 months for ownership of a house to transfer from the seller to the purchaser and today our transfer was completed. I no longer own my house and we’re currently staying with my inlaws until our new house is ready.

It also happened to be the day that we had organised for a removal company to come pick up all our goods and shove them in to a container in the middle of nowhere until we can move in to our new place in Cape Town, on the 1st of June.

On a stress scale of 1 to 10, today was definitely a 10. A lot went wrong with the move and things didn’t really go to plan. In fact, the movers have to come fetch more of our furniture tomorrow because it didn’t all fit in the truck. In-between trying to organise the move, I was trying to get some work in too.

As I was watching the day unfold and trying not to tear the little bit of my remaining hair out, it reminded me a lot of some of the development projects that I’ve worked on in the past.

Stressful development projects

Development projects usually don’t go to plan. Just like my move, things never follow the exact path that you’ve imagined in your head. Curveballs are thrown and you need to navigate around them.

Stress levels rise as things don’t go according to plan and it can all be quite overwhelming. I’ve been on projects in the past where I’ve been pushed to breaking point, kind of like I was today.

Feeling stressed about a project has seriously consequences. It can effect your ability to execute well, it can effect your relationships both personally and professionally and it can also effect your health (something I found out at the end of last year).

During my move today there was various times where I got seriously frustrated and it had a negative effect on the overall process.

What I learned today though, and the same can be applied to development projects, is that the as soon as you accept that things will not go to plan, the less frustrated you will be and you will also be much better at handling the different fires that need to be put out.

By knowing and accepting that there will be curveballs, you can anticipate them and easily navigate around them. If you are flustered and stressed about a situation, it becomes really difficult to handle it in a positive light with a happy outcome. Negativity breeds negativity and the same is true for positivity.

It’s definitely not always easy. Clients can get frustrated, managers may shout and people may be disappointed but at the end of the day, a stressful situation is what it is and you have 2 choices on how to deal with it. Accept it, learn and move forward or beat yourself up.

By the end of today, I had accepted the situations for what they were and tomorrow I will wake up and worry less about what may go wrong. By Thursday, everything will be in storage and I will probably have forgotten about all the stressful situations that came up the two days before and focus on the fact that the my possessions are safely in storage and ready for transporting to Cape Town.

So try to accept the stressful situations you find yourself in when working on development projects, deal with them to the best of your ability and know that you’ve done everything you can to make it right. You’ll feel less stressed and be a better developer for it.

Why you should unit test WordPress plugins

Probably the single biggest regret that I have in my development career thus far is that I didn’t start writing unit tests for my code at a earlier stage. I was kind of a late adopter to testing and only really started testing my code properly with unit and integration tests in the last 4 years.

If I had started writing tests earlier, I know for sure that I would not only have saved myself a ton of time, but also have become a better developer faster. That’s because testing has changed the way that I write code, for the better.

The biggest argument that is used against testing is that it takes too much time to write tests. And it’s hard to argue against the fact that is does add overhead to your development. But the amount of time that you’ll save in the long run by having a decent test suite far outweighs the initial cost of writing the tests.

It’s hard to convince developers who have never actually felt the real benefit of a good test suite of the long term benefits of testing. If you’ve never written tests before or worked with a codebase that is tested, then bear with me as I try my best to explain why you should unit test your own WordPress plugins.

3 reasons why you should unit test WordPress plugins

There are 3 reasons why I continue to write tests for my code.

Unit tests eliminate existing and future bugs

By writing unit tests, you are both testing your code in it’s current state and making sure that it does what it is supposed to do. And you’re also writing a test that can be used over and over again to make sure that your code is still doing what it is supposed to do as you add more functionality.

I recently took a piece of code in a WordPress plugin that was not tested, wrote a test for it and discovered that it was actually not doing what it was supposed to. If that code got shipped in it’s pre-test ready state, it would have probably resulted in support tickets and frustrated customers. Writing tests can be a great way to debug code that doesn’t already have tests.

Unit tests document your code

Before I look at a piece of code, I like to check if there are tests and if so, read through them as they usually tell you exactly what the code is doing and shouldn’t be doing.

By writing tests, you’re providing documentation for other developers who may work on the same codebase. Never mind other developers, have you ever gone back to a piece of code that you’ve written and been confused as to what is going on? I have, often.

Good tests are usually so much more effective at explaining the ins and outs of your code than badly written documentation or incomplete code comments.

Unit tests make refactoring code much easier

How many times have you refactored code, only to realise later on that your refactor broke some related functionality in your plugin? Perhaps the code that you refactored was not just written for the feature you were refactoring, but for other features too and you didn’t realise it. This happens often if you’re not writing tests.

With decent test coverage, you’ll know exactly if a piece of code you’ve written has broken some other part of your code because the tests will fail.

Are these good enough reasons to start unit testing your plugin?

I think so. And that is because the 3 reasons I listed above will do two things for you:

  1. Save you time in the long run. You’ll write more bug free code which will reduce support requests and debugging headaches. You will also not have to explain over and over again how your code works both to yourself and others.
  2. Make you a better developer. You will be able to push code with confidence knowing that you’re not breaking your plugin. You will also find that writing unit tests forces you to use good programming patterns and design.

If you’re still not convinced that tests are beneficial, all you need to do is work on a codebase which has decent test coverage and feel it for yourself. I know that I am a better developer for it.

Automate your WordPress development workflow

As you get older three things happen. The first is your memory goes, and I can’t remember the other two. – Sir Norman Wisdom

One of the keys to being a productive WordPress developer is to automate your WordPress development workflow. That is, wherever possible let tools and scripts do your work for you. The less work that you have to do and the fewer processes that you need to remember to follow, the better a WordPress developer you will be.

In a perfect world, we’d all be infallible and code would run bug free on the first execution. As we know, this world is far from perfect and as humans we are definitely prone to making mistakes as we code.

Automating your WordPress development workflow can bring your closer to being like that infallible developer we’d all love to be.

What to automate in your WordPress development workflow

There are a few crucial things that you need to automate right away if you have not already done so. They are:

  • Development environment. If you’re having to manually create a development environment every time you start a new project, reformat your machine or have someone else work with you on a project, then you really need get setup with a scripted development environment.
  • Code standard and listing checks. You should be automating the checking of your code against the WordPress Coding Standards. I’ve discussed why this is important before. Standards and linting checks should preferably be done as you write your code, but as a last resort, before each code commit.
  • Code completion. You will save yourself a ton of time by using a code completion tool that understands the WordPress codebase as well as the code you’ve written and can autocomplete based on that knowledge.
  • Snippets. Have a decent library of repeatable snippets of common WordPress code that you use often. These snippets should also include those pesky function calls which you forget the implementation details of and usually end up having to reference the WordPress documentation to figure out.
  • Boilerplates. Similar to snippets but on a larger scale, boilerplates save you from having to write structural code for your projects and let you skip straight to the important pieces such as the functionality. At the very least you should have a theme and plugin boilerplate that you reference when starting a new project.

There are some additional areas where you can look to setup automation. They include:

  • Deployment. Are you still FTP’ing files up to your server? You can automate the deployment of your code from your local development environment to live with a single command.
  • Unit test execution. Unit tests are a vital component to a maintainable project. I love writing tests. If you’ve got tests, automate the running of those tests either in your IDE or on commit.
  • Scripts for doing repetitive tasks. If you find yourself repetitively typing the same few commands in to a terminal to get something done, then you should write a shell/bash script to run those commands using a single command. A good example would be your Git workflow.

How to automate your WordPress development workflow

Luckily, WordPress has a thriving development ecosystem and there are great tools for automating your WordPress development. Here are some of my favourites:

  • VVV – A scripted WordPress development environment. Enough said 🙂 Also be sure to check out VV for creating sites on top of VVV. I’ve also written an article on setting up VVV with videos.
  • WP-Dev-Lib – This is a set of scripts that can be implemented on top of any WordPress project. They help automate the linting, running of tests and deployment of WordPress themes and plugins. See my article on applying WordPress coding standards for a video on setting up WP-Dev-Lib.
  • PHPStorm – I know that IDEs are not everyone’s cup of team and if you’re one of those developers who doesn’t like an IDE, I would urge you just to try out PHPStorm for a week and see what it can do for you. In terms of automation there are snippets (Live Templates), Emmet, the best WordPress autocomplete you will find anywhere and many more features that make your WordPress development bliss.
  • TextExpander – I use TextExapander to save code snippets that can be used inside PHPStorm or anywhere else really.
  • WP-Foo-Bar – I’m biased here since this is built by XWP and I work there of course, but choose any standards based WordPress plugin boilerplate and use it religiously.

That should be enough to get you setup with a well automated WordPress development workflow.

The sheer amount of tools and scripts available for automation may seem overwhelming. I would suggest that you start small but implementing a single item. Once you’ve got that down, move on to the next tool or script.

Before long you will have eliminated a lot of the grunt work out of your workflow and you will be writing cleaner and more reliable code.