So… my profile is now 16 years old. Pretty sure I had no idea what I was getting myself into back in April 2008.

Also, looking at my contrib history, I’ve been incredibly privileged to work for folks who’ve supported open source work for my entire career.

#currentStatus in #Chicago - 60° F apparent temperature change in less than 24 hours. 🤯 🏝️ 🥶

No Click Here

Here’s a periodic reminder of my favorite content writing guidance on the internet. It was written (by Aaron Swartz) back in 2001 and is still as relevant as ever.

When calling the user to action, use brief but meaningful link text that:

  • provides some information when read out of context
  • explains what the link offers
  • doesn’t talk about mechanics
  • is not a verb phrase

So, for instance, instead of saying:

To learn more about swimming at the YMCA, click here.

you could instead say:

The YMCA offers swimming opportunities for folks of all ages.

Making links like this is:

  • more accessible (screen readers will speak more relevant text),
  • more actionable (linking more words means a larger target for clicks/taps), and
  • more relevant (so you don’t have a bunch of the same words on a page).

</This ends your PSA. Carry on.>

We completed the December release of YMCA Website Services this morning and it’s another doozy. Quarterly releases mean it’s a big haul to the finish line, but demos like this morning’s where we can show it all off are worth it.

Drupal Community Governance, Transparency, and Sustainability

I applaud the Drupal community for its quick and overwhelming response to another instance of intolerance in our community. “Treat each other with dignity and respect” is one of our core values & principles, and upholding those values is the work of the whole community.

While we’ve achieved short-term success in the departure of a board member who does not share our values, I encourage us to continue understanding how such a person got there in the first place. Based on conversations in Drupal Slack, the DA Committees page is out of date and the minutes for the offending member’s nomination are vague. What logic led to this appointment in the first place?

Community members have flagged concerning social media posts from before his nomination to the Drupal Association board, but how deep into candidates’ public personas is reasonable for nominators to go? We need transparency to understand how DA Board members are vetted by the Nominating Committee. How are business goals and personal values weighed in the nominating process?

Issues have also been brought up by prior board members expressing frustration with the committee’s slate-based nomination process. If individuals on a slate are in question, we need to ensure that all Board members (appointed and community alike) are both able and empowered to raise those questions. What recourse do board members have to question a single member of the nominated slate?

In over 15+ years in the community, I’ve seen this process unfold time and again. Business development, infrastructure improvements, and “Drupal drama” all take time and effort to manage. The Drupal Association is small and scrappy and moves mountains to keep Drupal going, but it often seems to be strained in trying to be “everything for everyone”. How can we create a governance and funding model that “helps Drupal flourish” (the current work of the Board), “keeps Drupal alive” (the current work of the DA staff), and does it all sustainably?

Finally, hate and intolerance still plague our community. Let’s keep the momentum from this quick community action, build on it with the questions above, and continue to put pressure on our other leaders who refuse to stop hosting hate.

Discard crackers, aka “disco biscuits”

  • mix 1 tbsp butter per 100g discard
  • add a pinch of salt and any seasoning
  • spread on parchment, thin as possible
  • 10 min @ 350°F, score, another 10-15 min

🍞 #baking via Reddit

Trees Not Tees

On March 17, 2022, Kristy @EstherRawson shared a preliminary survey that described over 2800 heritage trees to be cut down for the combined Jackson Park/South Shore PGA-caliber golf course. The course has been in the works since the South Lakefront Framework Plan was released in 2018. We already knew about the planned destruction of the South Shore Nature Sanctuary but this newly FOIA’ed information brought the level of planned destruction to a new level. More discussion of the fight to save the Sanctuary was discussed on @CityCastChicago.

I believe it’s essential to stop this destruction. I’ve put together a collection of merch to help spread the word in Hyde Park’s 4th on 53rd parade. All proceeds will benefit the South Shore Nature Sanctuary.

When you get your merch, please review the links above and consider these talking points:

  • Chicago Parks District should stop the plan to remove 2800 heritage trees from Jackson Park
  • Money from the planned project should be used to improve existing facilities in Jackson Park and South Shore
  • Community golfers will be shut out of the course that they’ve come to know and love by periodic tournaments, inaccessible course design, and increased fees.

For more info on the parade and more, sign up for the South Side Parks email list.

We’re two sleeps away from MidCamp and 😱. Despite the exhausting whirlwind of 2020/1 our team has been incredible and we have 4 awesome days planned. People talk about “chosen family”… well this is my “chosen project team”. We’re all here because we want to be, and it shows. 💙🎩🙌

Composer alias vs composer replace for downgrading/removing drush

I was wrestling with composer yesterday to try to get Drush 10 out of a project where I wasn’t ready for it (because while Aegir is amazing, drush 9+ support is still a WIP).

My first instinct was to use “alias”:

composer require drush/drush:"8.4.6 as 10.3.6" --update-with-all-dependencies

That worked, but I don’t actually need drush to be installed in my prod encironment at all, but it is in require in a dependency. That’s when Andrii told me about “replace”:

    "replace": {
        "drush/drush": "^10"

In… a fun loophole/feature, if you use replace but don’t specify a replacement, it acts like ignore.


I had a wonderful #OpenSource moment yesterday...

Our team at YMCA of the USA was midway through pushing updates to 150 sites on our Drupal PaaS offering when another Open Y partner agency’s team shared in Slack that they’d discovered a major issue with the code we were in the middle of deploying! 🙀 Even worse, when I started looking at the issue, it turned out to be a bug that I’d helped to introduce into the codebase. 🙀🙀

Over the course of yesterday, teams from around the world collaborated to push not one, but four fixes that we’d discovered. This was all made possible because the Open Y community has decided to work collectively, even as agencies competing for the same customers, in order to extend the YMCA mission into digital spaces.

Thanks to everyone who helped make these fixes possible. Our sites are better together!

The child decided to pack her own toys up to give herself for Valentines Day which she’s now calling Christmas because we haven’t taken our tree down. We all need a little more joy right now…

What were great virtual conference experiences people had this year? What did organizers do to make it more human and less of “just another Zoom meeting”?

We got walkie talkies…

Kid: Come in, Dad, over. Me: Rodger Rodger, over. Kid: Don’t call me Rodger!

Walkie jokes must just be built-in to our systems now. 😂

Composer tip for the day:

This will most likely fail and cause you endless pain and sadness.

composer require project/with-lots-of-dependencies:1.2.3

This will work. Makes developers happy.

composer require project/with-lots-of-dependencies:1.2.3 –update-with-all-dependencies

One year ago, on this day, I was drinking a beautiful beverage, indoors, in a place that is not my home.

I hope a year from now that those qualifiers seem mundane.

Kiddo got a Spirograph. I experimented by adding Sharpies to the mix.

If you DM a person...

I shared some advice in our work chat today:

If you DM a person you have one person helping you. If you ask in a group chat, you have the whole team collaborating.

If you give an answer in DM, you help one person. If you give an answer in a group chat, you help the whole team.

This isn’t a 💬 (quote), but a reflection of my own experiences working on highly collaborative teams and open-source projects.

She made homemade biscuits over the holiday. I put eggs, fried onions, and cheese in them. It was a delicious mess. 🥞🤤

A messy breakfast sandwich on a yelliw plate.

Custom domains, Cloudflare, and

If you use Cloudflare for your domain as I do for, you may have to make some modifications in order to get your domain set up with

  • In Cloudflare’s SSL/TLS settings, turn SSL “Off”.
  • In Cloudflare’s DNS settings, be sure to “grey-cloud” the CNAME and A record pointing to
  • Once detects the DNS change and issues the certificate, leave Cloudflare SSL off. now has you covered!

The road ahead

I’ve been stuck in analysis paralysis about how to do a blog for about a year now… experimenting with Jekyll, looking into Hugo. My goal was to do as little development as possible, because this place should be about making words, not code. looks super, and @manton has already been helpful in getting me set up. Here’s to the road ahead.

When is a number not `input type='number'`?

When it “only consist[s] of numbers but isn’t strictly speaking a number”. See Why the GOV.UK Design System team changed the input type for numbers for more details.

While Drupal supports #pattern on FormAPI elements, there’s no top-level property for #inputmode. That can be added via #attributes, like:

$form['textfield'] = array(
  '#type' => 'textfield',
  '#title' => 'Any number of digits',
  '#pattern' => '[0-9]*',
  '#attributes' => [
    'inputmode' => 'numeric',

I am here (and here’s a beer).