Steve Grunwell

Open-source contributor, speaker, and electronics tinkerer

8 Highlights from Engineering @ Growella

If you recall, I launched the Engineering @ Growella blog at the beginning of 2017. Since then, I’ve been publishing at least once a week on that blog, but this site has been neglected as a result, which is unfortunate.

I’m very proud of the content that’s being published on the Engineering @ Growella blog, however, so I thought I’d take a moment to highlight some of the better pieces from the last two months:

Automatic database backups to Amazon S3

Last week’s article had the unfortunate timing of being published just hours before a typo took down a significant portion of the Amazon Web Services infrastructure, but it outlines how I’ve automated database backups on all Growella servers, using Amazon S3 as an off-site repository for database backups with automatic expiration of old backups.

How to register custom field settings in Gravity Forms

After doing a fair bit of custom integration work with Gravity Forms, I was annoyed that there didn’t seem to be a good guide that explained how to add custom field settings (properties) to Gravity Forms fields. I ended up writing this guide, which has since served as the foundation for some open-source work on GitHub.

If this looks familiar, I first touched on the topic back in December in Custom field IDs for Gravity Forms Fields.

One-time callbacks with the WordPress Plugin API

Another one of those things that I’ve found myself having to do at various points in projects, but never found good documentation around, is the idea of a one-time callback for a WordPress action or filter (e.g. do_action_once() or do_filter_once()). My good friend John Bloch, a former Lead Web Engineer at 10up, was also willing to give an early draft of the post a code review and make recommendations to help reduce the footprint of the code.

Simplify WordPress plugin audits

One habit I picked up in my time at 10up that I’ve been unable (or unwilling) to shake is performing audits on plugins before installing them on a site. There are a lot of well-meaning plugins available that fail to do simple things like input sanitization, output escaping, using prepared statements when interacting with the database, and more.

You may recall that I launched WP Enforcer, a Composer package that automatically registers pre-commit Git hooks to run PHP_CodeSniffer, in late 2015. Around the same time, I also started working on the 10up-Code-Review ruleset for PHP_CodeSniffer, which was designed to streamline code reviews by focusing only on important issues like security and ignoring less-significant items, like naming schemes, whitespace rules, etc. While not a replacement for proper code review, the 10up-Code-Review ruleset can find issues in a project in mere seconds that could take several hours to find via manual review.

In Simplify WordPress plugin audits, I lay out the benefits of performing plugin audits and show how painless it can be for teams not already doing it.

Tracking server-side HTTP redirects with Google Analytics

Growella makes its money through affiliate programs and lead-generation, but we’d prefer not to have long, ugly affiliate URLs (e.g., so I was asked to implement a branded redirect system (e.g. that could be controlled in a central location.

My go-to WordPress plugin for user-controlled redirects is 10up Director of Engineering Taylor Lovett’s Safe Redirect Manager, and it checked all the boxes in this case except one: our team also wanted to be able to track clicks through the affiliate links in Google Analytics, separate from the partner-provided affiliate dashboards.

After some searching, I stumbled upon the Google Analytics Measurement Protocol, a server-side API for posting data to Google Analytics. Using the WordPress Plugin API and Safe Redirect Manager, I’m able to post redirect events from Safe Redirect Manager to Google Analytics.

Using Jetpack Popular Posts in WP_Query

This was another one of those “I’ve had to do this a dozen separate times, but there isn’t a great guide out there to explain how” moments: how do we leverage Jetpack’s “Popular Posts” functionality to create a WP_Query object filled with the most popular site content?

This post also goes a step further, showing how to order by the most popular content without limiting yourself to only popular content.

Show or hide meta boxes when changing the WordPress page template

Earlier in my career, I was absolutely in love with Advanced Custom Fields, mainly because it helped me create powerful editorial experiences without having to muck around with the often-confusing WordPress Settings API. Unfortunately, once you reach a certain level of client or team, tools like ACF begin to show their cracks; either we’re loading a lot of plugin for little benefit, or maintaining ACF functionality across multiple developers and environments.

One of my favorite features of ACF was the ability to conditionally show or hide custom fields depending on the post editor context. Want to only show this field for posts in a particular category, or for specific page templates? Advanced Custom Fields made it easy to configure.

This post shows how to easily replicate some of the nice ACF conditional visibility behavior without requiring Advanced Custom Fields. With a little bit of JavaScript, we can show or hide custom meta boxes depending on the post/page template or any other setting!

Speed up deployments using gulp-changed

One of the things I was most excited about getting to build Growella from scratch was determining the deployment workflow. At first, I tried running Jenkins on a cheap Digital Ocean server, but had less-than-awesome results. I ended up moving Growella to DeployBot (who I was familiar with through my time at 10up), but found that our [atomic] deployments were taking quite some time.

As it turns out, DeployBot was looking at the modification timestamp to determine if a file had changed since the last deployment. Unfortunately, the build script that I had written (load WordPress + plugins via Composer, then replace the wp-content/ directory with the version from our repository) effectively touched every file in the site, causing even simple style updates to take 15-20min to deploy.

I was able to work around this using the gulp-changed package, ensuring only files that have actually changed are copied into the build directory (and thus deployed by DeployBot).

More content is coming!

My goal is to continue to publish weekly on the Engineering @ Growella blog (posts are normally scheduled for Tuesday mornings at 10am Eastern), but I do want to continue writing here, too. My apologies for the lack of content as-of-late, but please be sure to check out the Engineering @ Growella site and follow @GrowellaEng on Twitter.


Schemify: Automatic structured data for WordPress


Brewing your own cold-brew coffee in a French Press

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Be excellent to each other.