Latest Posts

If I wrote it, it should be here. I went into software, not literature and my writing reflects that.

2026

What Is a Bookmark?

I've been spending some time building a bookmarking service on ATProto and, as part of that, trying to understand how people think about lexicons and interoperability. In talking it though at last weeks Side Project Saturday, Jared was kind enough…

ATProto Lexicon

2025

Obscure HTML Attributes on My Radar

I don’t reach for these every day, but they fascinate me. Some are old, some new, and all of them feel like hidden corners of the spec worth exploring. What I like about digging into HTML attributes is that they…

attributes HTML Markup

A Sabbatical as a Space to Reset

This summer I took my first sabbatical. It was a relatively new policy and I didn’t have much time to plan unless I wanted to push it into next year. By the time it was official, the kids already had…

Europe Sabbatical

My Favorite Pseudo Elements

Most people don’t spend time thinking about CSS selectors, and honestly, even most developers probably don’t have “favorites.” But every now and then, I catch myself appreciating a few of the lesser-used pseudo-elements. They’re easy to overlook, but I like…

backdrop CSS first-letter pseudo selection

Rewiring Times Wire

Back in 2009, I submitted a project to The New York Times’s internal Tech Challenge: a demo called Times Now, later renamed to Times Wire. The idea was simple: a clear, reverse-chronological stream of every story published to the homepage. It was…

Javascript The New York Times

Before It Had a Name: The Founding of Quartz

Looking back at the beginning of Quartz In early 2012, I was living in Seattle. I'd left The New York Times less than a year earlier after a long stint but I was missing media. I was on a quick…

Quartz

URL Design Principles

URLs are the most overlooked part of web design. People obsess over page speed, conversion rates, and SEO rankings, but then let their CMS generate URLs that look like they were created by a stranger they met on the subway.…

url User-Experience UX WordPress

Blank Page Anxiety

I have a notebook. I spent a long time searching for it, the right paper, the binding, the ideal shade of off-white. The plan was simple: a place for ideas, projects, and inspiration. The reality has been mostly empty pages.…

notebook pages writing

How to have an anonymous website

You might want to create an anonymous website for all kinds of reasons. I'm a strong believer in personal privacy, not in supporting anything illegal. I enjoy thinking through scenarios I don’t actually need to worry about, like how I’d…

domain hosting privacy

2023

Your Content and AI Training

It’s very in coming, but we’re slowly getting the means to indicate that our site content should not be used in training sets for generative AI models. It’s still unclear whether existing web crawlers were used to train current LLMs…

AI Bots Crawling LLM robots.txt

Javascript Array Methods

[■,●,■,▲].every(●→true) ⇒ false [■,●,■,▲].filter(■→true). ⇒ [■,■] [■,●,■,▲].find(●→true) ⇒ ● [■,●,■,▲].findIndex(●→true) ⇒ 1 [■,●,■,▲].fill(●) ⇒ [●,●,●,●] [■,■,■,■].map(■→●) ⇒ [●,●,●,●] [■,●,■,▲].some(●→true) ⇒ true

arrays Javascript

2022

Modify default Slug for WordPress Posts

The default slug is generated from the initial title. If the title is long, this can be annoying. I prefer short URLs without common filler words like “the,” “and,” or “I.” This setup also limits slugs to a maximum of…

slug WordPress

Adding humans.txt to WordPress

humans.txt is a simple but meaningful way for web developers (and other contributors) to take credit for their work and leave a trace of their presence on the web. Given enough time, everything a web developer touches tends to disappear. The…

humans humans.txt PHP WordPress

Adjustments to WordPress

A collection of useful functions, actions, and other ways to alter WordPress. Change default slug for Posts The default slug is based on the initial Title. If the title is long htis can be very annoying as I personally like…

PHP WordPress

Creating your own Twitter Archive

Twitter was a really important service for me, but that’s changing quickly and I’m not too sure what comes next. What I do know is that I’ve been on it for 16 years, and that means something to me. As…

PHP Twitter

bash_profile for macOS

Rather than re-inventing this every few months, or years, I'm sticking it here for posterity. Nothing here is sensitive. vi ~/.bash_profile The file # Library Paths # ===================== # These variables tell your shell where they can find certain #…

bash macOS profile

Useful mods to the SEO Framework Plugin

I love this plugin, The SEO Framework for WordPress. Aside from SEO benefits and managment options it adds criticial controls for the editorial team in managing the various META tags we rely on for social previews. It has numerous hooks and actions, though…

Code PHP SEO WordPress

2021

macOS Customziations

Disable Dictionary.app Disable the Dictionary.app so it doesn't always pop-up when you accidentally highlight something, or sneeze. Make these changes in the System Preferences but note that you may need to adjust settings on some apps too. Open System Preferences > Keyboard…

macOS

Essential Web Dev Apps for MacOS

Terminal & Network iTerm Charles Transmit Transmission TunnelBear Fonts & Typography BirdFont Platform News Preview IDE & Rleated utilities Xcode Vagrant Manger VirtualBox VSCode Image ImageOptim Acorn Design & Wireframes Figma (and Font Installer) Video & Encoding VLC MetaZ HandBrake Utilities…

apps development frontend macOS

sudo make me a sandwich

My usage of sudo has gone down over the last couple of years, but enabling Touch ID on my Mac for use with sudo has been a huge win. Yes, you have to take your fingers off the keyboard for this so…

macOS sudo TouchID vi

2020

WordPress Notes

Collection of code fragments and useful notes for WordPress Basic word-count by post, from databse SELECT `ID`, `post_date`, `post_name`, `post_type`, `post_status`, `post_title`, `guid`, SUM( LENGTH(`post_content`) - LENGTH(REPLACE(`post_content`, ' ', '')) + 1 ) AS 'Wordcount' FROM `wp_posts` GROUP BY `ID`…

SQL WordPress

PHP I Keep Returning Too

Nothing earth shattering, just a collection of code fragments and functions I keep re-writing and re-using... Basic compression of CSS for output // Remove comments $cssText = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $custom_css_field); // Remove space after colons $cssText = str_replace(': ', ':',…

Code PHP

2019

Web Performance: Year in Review for Journalism

The realm of web performance goes deep into the perceived user experience of load time and the actual load time. My specific interest is in media and presenting information to readers - typically article pages. For any given news site,…

WebPerf

Flying with Children

Your mileage will vary depending on age and disposition but this is what works for me. TSA Pre-Check via Global Entry I hate this in principle but here I am. If you don't have this get Global Entry which includes…

Children Global Entry kids nausea travel

2018

Simple GDPR Lockdown

When the GDPR privacy regulations came into effect, a lot of the discussion focused on consent banners, privacy policies, and legal obligations. What received less attention was the practical reality of implementation. I suspect many of the pundits had never…

GDPR Javascript privacy

2017

25 Years of NYTimes Crossword Data

I first started reverse-engineering the .puz file format about 6 years ago. Its a very efficient crossword format that goes to great lengths to compact the data into a small payload. (Update: In September 2021 the NYT no longer uses this file format)…

crossword CSV NYTimes

The Idea of Quartz

a.k.a. “I found an old bunch of screenshots” Quartz launched on September 24th, 2012 at 9:55am EST. As it comes up on 5 years of age, I thought it was overdue to test my l33t medium typing skillz. Quartz started…

design Quartz Startup wireframe

2014