Steve Grunwell

Open-source contributor, speaker, and coffee snob

Assorted patterned tiles

Demystifying Regular Expressions

Early in my career, I stumbled upon this regular expressions cheat sheet by Dave Child in one of those “10 cheat sheets every developer should have”-type round-up articles.

I had been using regular expressions for several years before I first noticed that other developers were struggling. Patterns that seemed natural to me were complex ciphers to my peers, and an audible groan would echo through the office whenever a solution that leveraged regular expressions was proposed.

Here’s the rub: regular expressions don’t have to be that hard. They certainly require a bit of getting used to and some practice, but regex patterns are tremendously useful when validating data, searching files, or even filtering tweets.

Continue reading→

A close up of a pair of stainless steel knife blades

Writing Custom Laravel Blade Directives

Though it’s far from the top of the list of most celebrated features, Laravel’s Blade templating engine makes it really nice to work with data on the front-end of our applications. With built-in helpers for handling loops, conditionals, and sub-views, Blade gives us a nice way to write dynamic templates that don’t feel like a bunch of PHP mixed in with HTML.

Were you aware you can author your own Laravel Blade directives? The syntax is probably a little under-documented, but it can be an incredibly useful tool if you find yourself applying the same patterns over and over. In this post, I want to show you a Blade directive I find myself using in pretty much every application I build: @activeIfInRouteGroup.

Continue reading→

Stacks of vintage, sepia-toned photographs

Paid Support for Legacy Libraries

A few weeks ago, I was talking to my good friend Eric Mann about an open-source package he maintains. This particular package has quite a number of downloads and active users, despite Eric trying to abandon it a few years ago. He’s since restarted development on it, but now he faces a problem: people are upset that he’s dropped legacy PHP version support.

This particular package is popular within the WordPress ecosystem, which is big on backwards compatibility. Despite the fact that both PHP 5.6 and 7.0 stopped receiving even security updates at the end of 2018, there are still plenty of users out there running their applications in old, insecure versions of PHP. As a result, some people were rather upset when Eric stated “I’m not going to spend my [limited] time supporting EOL’d versions of PHP.”

Some commenters were quick to jump in with remarks ranging from “well, it doesn’t take that much time to support older versions of PHP…” to “WordPress supports older versions of PHP, so should you!”, but Eric remained firm: if you want support for older versions of PHP, you can either pay me for my time or contribute the code yourself.

It may sound a little harsh, but I’m 100% with Eric on this one: he doesn’t owe anybody his time and effort. That’s time he could be spending with his family, out hiking, or working on projects that he enjoys. Heck, knowing what Eric can do, back-porting support for old versions of PHP should be way down on his list of priorities.

Continue reading→

A home sitting on a midwestern, prairie homestead.

Simplify Project On-boarding with Laravel Homestead

Despite working on Liquid Web’s Managed WordPress and Managed WooCommerce hosting products, a fair amount of the development work I do these days has very little to do with WordPress. In fact, my main project right now is using Laravel, and it’s the sixth Laravel application (depending on how you count projects) I’ve worked on in just under two years at the company.

Laravel’s an incredibly powerful application framework with a thriving ecosystem. Thanks to tools like Composer and Packagist, I have access to thousands of libraries, extensions, and utilities to help me build the best applications possible. Even out of the box, the framework has support for (among many other things) multiple database and caching engines, event-driven architecture, and websockets, giving me a strong foundation for building modern web applications.

Of course, incorporating multiple platforms and tools into a single application can make on-boarding new team members more difficult. How do you make sure they’re running the right versions of PHP, your RDBMS of choice, Redis, and more?

Continue reading→

One row in a document archive, full of boxes and binders

Automatic, Whole-Home Time Machine Backups

Over the holidays, I decided to tackle a problem that’s been on the back-burner for a while: how can my wife and I automatically back up our Macs to a common Time Machine drive? We already have a router I’m happy with (the NETGEAR R6400, which is a couple years old now), so I didn’t want to replace a solid router with Apple’s Time Capsule, especially given that the line seems to have been discontinued. Is there a way to keep a common Time Machine drive on the network?

Up until this point, Kim and I have gotten by with our own Time Machine disks that live on our desks: when we’d remember, we’d plug in the disks and ensure a backup was made. I can’t speak for Kim, but I know my backup history was…spotty, to say the least.

When Kim started her own business in 2017, we upgraded her older MacBook Pro with a new SSD and kept the old drive housed where the rarely-used optical drive used to live. All told, she has just shy of a terabyte of storage on her machine, but was (just barely) backing up to a 500GB Time Machine disk. Wanting to ensure that client files and portfolio pieces alike were backed up securely, Kim asked if I could set something up to make the process easier; this is what I found.

Continue reading→

An exposed lightbulb sitting atop a pile of books

Atomic Deployments from Scratch

Years ago, a mentor of mine introduced me to a Ruby-based server automation tool called Capistrano, and I immediately fell in love. Ready to deploy a new release? Rungit push && cap production deploy, then you’re done. Even better, Capistrano introduced me to what’s colloquially known as “atomic deployments” — checking out a full copy of the codebase and using symlinks to point to the new release for a zero-downtime deployment — which has since been my gold standard for deployment methods.

I continued to use Capistrano for a few years, until I started working on projects (and teams) large enough to justify a proper continuous delivery (CD) tool. Suddenly, building the application locally and pushing up with Capistrano became more complicated; at the same time, services like DeployBot began offering atomic deployments right out of the box, so it was easy to get up and running.

What about services that don’t offer atomic deployments as a default? I recently deployed a Laravel application via Codeship, where atomic deployments to a VPS becomes more complicated; here’s how I approached it:

Continue reading→

An assortment of patch cables connecting various components

Routing phone calls to volunteers with Twilio

In the past week or so, I’ve been working on a Laravel application that enables groups of volunteers to be added to a call tree; a phone number comes in, then gets routed to one of the active volunteers’ phone. A lot of the core functionality is there, but the app isn’t quite ready to release to the general public. There’s something of a time-crunch, however, as the main reason for building the application is to connect people who need rides to their polling places with volunteers in the days leading up to the critical 2018 midterm elections.

Here’s the concept: someone in need of a ride calls a Twilio number, which then rings up to ten (10) volunteers’ phones. Whomever picks up first gets the call, and they can work through arranging transportation.

Building the application has been an awesome introduction to telephony service providers like Twilio, which combine voice and SMS messaging with web applications. Using Twilio’s TwiML (Twilio Markup Language), I can write simple XML documents to describe how to respond to different messages. I have a lot of features planned as far as routing calls more intelligently and letting volunteers mark themselves as unavailable, but I wanted to get the bare-bones TwiML out to the public as far ahead of Election Day as possible.

Continue reading→

A pile of LEGO bricks spread out across a hardwood floor

Understanding the functions.php file in WordPress

If you’re just getting started with WordPress, there’s likely a lot of new terminology being thrown at you. Beyond fundamentals like “themes” and “plugins”, you’re probably seeing “actions”, “filters”, and a ton of code snippets with instructions like “just add this snippet to your functions.php file.”

Let’s take a step back and look at WordPress’ functions.php file; what it is, where it lives, and how it works. Once we understand those points, we’ll learn how to add snippets to our WordPress sites without having them accidentally overwritten.

Continue reading→

A home sitting on a midwestern, prairie homestead.

Using user-customizations.sh in Laravel Homestead

Today, Laravel Homestead maintainer Joe Ferguson tagged version 7.16.0 of the Laravel Homestead library. The announcement tweet includes “Adds support for user-customizations.sh” which, probably doesn’t mean much to anyone who hasn’t followed Pull Request #932 over the last few days. As the person who opened that particular PR, I figured it might be nice to document the motivations.

Continue reading→

A basket full of assorted vegetables

Streamlining your test suite with PHPUnit Data Providers

In every testing talk I’ve attended (or given), there’s one stand-out feature that often has the audience saying “whoa, I had no idea you could do that!” No, it’s sadly not “hey look, you can reliably build quality software with a much lower chance of defects or regressions!”, but rather the inevitable use of PHPUnit’s Data Providers.

With Data Providers, our test suite can become more readable and maintainable while making it trivial to add new testing scenarios. Best of all? PHPUnit ships with Data Providers right out of the box.

Continue reading→

Page 1 of 13

Be excellent to each other.