JSON is good at a lot of things, which led me to think it's great for configuration files. But it's not. YAML is the way to go.

Facebook's using it. Twitter too. Slack. And, now iOS 10. The metadata on your website is getting more important.

I've been impressed with Vagrant and with Ansible, but my provisions always took an extra step on Ubuntu 16.04. How to get Vagrant to install Python before provisioning the box.

Using RabbitMQ to separate application logic from transactional email logic.

How I was able to get nginx serving HTTP/2 and a Let's Encrypt certificate on my Ubuntu 14.04 server.

The default user agent header set by NSURLRequest is awful. Do yourself a favor and change it.

PHP's IntlDateFormatter::SHORT renders some locales with 2-digit years. I explore how to hack it to render all locales with 4-digit years.

How I embed ExpressionEngine templates into a Freeform Notification templates so they can be tracked in git.

An upstart configuration for node on Ubuntu 14.04 that uses navtive options rather than resorting to "script".

Configuration does not belong in the database. We've known this for years. But configuration also does not belong in git.

Stash is a powerful tool for templating in ExpressionEngine. Used the right way, it can improve the readability of templates. Used the wrong way, it can make a mess of things.

It's been hammered over and over that, on the web, there is no fold. And rightly so. But lets break the rules and make one anyway.

After reading "Trello as a CMS," I was inspired to automate my tweets from a Trello board.

Writing an ExpressionEngine Add-On can be daunting. But the Plugin is a no-nonsense, easy place to start.

Far-future cache headers are important for the performance of a site. But they also require the the ability to bust the cache when an asset changes. But how do you do that in ExpressionEngine?

Max Length is an accessory that provides a small, unobtrusive indicator for how many characters an input has left before reaching its maximum length.

Black and white. Good and bad. The right way and the wrong way. It would be great if web development fell into nice neat little categories. It doesn't.

Your git history is like a book. It can read like a rambling stream-of-consciousness tome. Or you can squash your commits to read like a sharp-witted novella. Do us all a favor and squash your commits.

I work on the internet, where I mostly build and maintain websites. Changes on the web are instantaneous. But recently, I worked on an iPhone app where this isn't the case. And it got me thinking about release cycles and their impact.

"Build it and they will come" doesn't work on the internet. its5.info needed a strategy. There were several options I knew wouldn't work. But Twitter provided a world of opportunity.

On a cold day in late March, 2014, someone just trotted out the old phrase, "It's 5 o'clock somewhere," and I immediately wondered where? That's when I had the idea to build a website that tells me where in the world it's 5 pm.

"That's a lot of markup for an image." The primary concern I've heard about responsive images since I wrote my responsive images article is that they're just too verbose. Things just got better. <fig…

Communication is important. There are so many ways it happens: face to face, phone, email, text, instant message. It's often not thought of as such, but git is also a tool for communication. I've bee…

What does a good move in 2048 look like? What makes one move any better than another? After getting hooked on 2048 for a while, I decided to program an AI solver for the game, and those are the funda…

Switch is a simple ExpressionEngine field type for choosing between two or more values. Do you need to mark an entry as featured or standard? Switch does it. Do you have two or three options, but a d…

Recently, I started getting away from the jQuery pattern of checking the length of an object before writing code. Instead, I've found myself wrapping my selector in jQuery's <code>each</code> method,…

For a recent project I worked on, the mock-up for the home page carousel's images were huge. 1900×696 pixels huge. Personally, I've never used responsive images before (long overdue), but I decided t…

About a year ago, my wife and I had a crazy idea to write a children's book for our daughter. Even crazier, I decided to illustrate it. Just recently, we finally finished it and had it self-published…

With as many visits as my site gets – and by that, I mean very, very few, actually – any visit that I make to the site can really skew the analytics. On the one hand, I'm my best visitor: I've been t…

I've long been a huge admirer of SVG (W3C's Scalable Vector Graphics). As retina screens proliferate, SVG allows web developers to create images that look great on all screens, regardless of the reso…

Yesterday, I stumbled into a conversation about mobile browsing with Peder Aadahl (of 168 Opportunities fame) and Curtis Jacob (of Hardy Boys Casefiles Encyclopedia fame), and it helped me articulate…

"I concluded last year that mobile usage is increasing, and it's time to start thinking about your mobile customers. Now, with one in four visitors coming on a mobile or tablet device, and mobile usa…

Far-future cache headers are important for the performance of a site. But they also require the the ability to bust the cache when an asset changes. But how do you do that in Node.js?

I recently created a landing page for a Score Lab PPC campaign where potential customers either convert or bounce. If a customer converts, hooray!, I throw a little party in my head. But most potenti…

This past week, while researching for another post about IE8 and responsive design I'm thinking about writing, I pulled stats from a large number of Google Analytics profiles on all of the widths of …

I still remember it. That "s", that little "s". In the basement of my childhood home, on an old vanilla computer with one of those monstrous CRT screens, I stared at that C code for hours, but nothin…

So, you're building a new website. And you don't want to just throw your money away, so you'd like your shiny new website to last, what, about 5 years? That sounds reasonable. (Most 5-year-old websit…

It's a really simple app. It just does this. It just does that. On occassion a person or a small business will pitch me to build an app – a simple app – for them. But what they don't see is that what…

It's 2:30 am. Somewhere in San Francisco, California, a woman is in a coffee-fueled programming bender. For the past five hours, she's been immersed in her program, unstoppably producing code. She's …

I have always liked the three-tier architecture. In my .NET days, I frequently used .NET Web Services, and then later WCF Services to structure large applications. When I started Score Lab, I started…

I've been writing my own service, Score Lab, for sports schedules, scoring, and standings for nearly a year now. Just recently, I had the opportunity to use try it out on a real competition, the Clic…

I'm a big fan of node.js. Of the many things I like about it, my favorite is the community's focus on small, reusable components. I can't begin to count the number of times I've been happily developi…

It was late afternoon on Friday and I was more than ready to go home after a long week when I opened an email about a regression on a client website. Which, of course, needed to be fixed before the w…

"We have been using a Progressive Enhancement approach much more in relation to our web work. In a nutshell, this means we provide a good looking site on all browsers, then on more modern browsers, …

"The mobile user has been typecast." Read the whole article on the Click Rain Blog: The Shifting Mobile Landscape