• Projects
  • Archive
  • Links
  • My Christian Rap past has come back to haunt me. (Do they know I was more of a John Reuben guy?)

    Screenshot from a McDonald’s mobile order: your order (voice code KJ52)
    → 8:52 PM, Aug 7
    Also on Bluesky
  • Abstractions, Future-Proofing, and a Reasonable Amount Of Effort

    I’ve been looking into Tempest. It’s a new PHP framework that is built for modern PHP: type hinting, property accessors, the works. I’m most excited about its approach to discovery. It closely models what I’ve been building towards in Smolblog’s framework, but with infinitely less manual configuration.

    So this past weekend, I started playing around with seeing if I could get Smolblog’s core domain model working. And… I ran into a speed bump. It wasn’t hard to get around, but I was curious about the reasons behind it. And when I asked about said reasons… well, apparently I wasn’t the first.

    Which brings me to this blog post. This isn’t me trying to die on this hill or even claim some semblance of high ground. I’ve just been thinking about this a lot since the topic was broached and I wanted to get my thoughts in order. But I especially want to emphasize: Nothing in here is meant as an insult to others or a statement on the quality of their code. I have my perspective, and they have theirs, and none of that means we can’t work together.

    That being said, let’s get some context.

    The Umpteenth Rewrite

    I’ve been working on Smolblog for way too long. I started it as a WordPress plugin, but as I learned more about SOLID principles and modern Object-Oriented software, I realized I had bigger ambitions. Especially when it felt like what I wanted to do and how I was thinking about content management was running headlong into some of the decisions WordPress made about how it approached things.

    So, I made a decision that honestly haunts me to this day: the core of Smolblog’s code would be framework-independent. I say “haunts” because while it’s meant the code I’m writing is—theoretically—incredibly versatile, it also means I can’t take advantage of any of the shortcuts that come from using a framework.

    That being said, while development has been slow, it’s also forced me into some design decisions that I’m happy about:

    • I’ve ended up with a distinction between Value and Service objects: Values have state but no logic. Services have logic but no state. It’s helped me stay closer to making “single responsibility” objects.
    • I haven’t had any real input or output with the system, since a user interface is an implementation detail. Which means the only way I know something works is to write a test. So I’ve got a lot of cussing tests.
    • If the code is something that is core to the application, it goes in. If it’s an implementation detail, it gets an interface and I move on.

    That last point was helped a lot by the existence of PSR interfaces. These are recommended standards for pieces of infrastructure that are often found in frameworks. For a concrete example, even though I wrote my own dependency injection container, the core domain model only needs something that implements PSR-11. Which means, if I want to finally stop building my own stuff I can swap out my container for the one in Tempest!

    Except… Tempest doesn’t implement PSR-11.

    The Other Side Of the Coin

    Naturally I asked in the community chat about this, trying to get an idea of the reasoning. Brent, the lead developer/architect/founder? of Tempest pointed me to an older blog post of his, with the note that the “long version” (describing how it pertained to Tempest specifically) still needed to be written1. Between that and some of the ensuing conversation, I gathered a few points:

    • The design of Tempest’s components don’t always match up with the PSR specification.
    • Having interoperability between frameworks doesn’t make sense when code is tied so closely to its framework.
    • The interfaces designed by the PHP FIG can be outdated or only fit for a specific purpose.
    • For PSR-11 specifically, Brent cites two frameworks, Laravel and Symfony, who both implement the Container standard yet add several methods on top of it. Any real use of the class would inevitably be tied to the specific framework.

    I highly encourage you to read Brent’s post, especially as at the end he acknowledges the popular use case of smaller packages being used in multiple frameworks.

    It’s that particular use case that I end up falling into for Smolblog: the core domain model isn’t written as a monolithic application but as a library to be used by an application. There’s so much more that goes into an app than just the core logic; in fact that’s often some of the smallest parts! But in this particular case, I wanted to take the time to get this core logic right… and I had another motivation.

    Fool Me Once

    I didn’t realize until I went to write this paragraph how ingrained the idea of limiting dependencies is to Smolblog. The first essays around the idea of Smolblog came in the wake of poorly-implemented policy changes at Tumblr. The original feature set leaned heavily on POSSE, the IndieWeb idea of owning your own content.

    So it makes sense that I wanted to reflect this idea in code. I didn’t want to be trapped into a particular framework’s idioms and then find out later that it would have been better to pick a different one. Part of this came from writing a different app with a WordPress backend and realizing… I wasn’t getting anything out of WordPress that I couldn’t get elsewhere with less hassle.

    So while I do plan on using Tempest—and I have the highest respect for Brent as someone that’s actually doing the thing he blogged about!—I wanted to push back against this:

    I’m more than happy to ditch “interoperability” — what does that even mean when you’re building a project closely tied to a framework and never intend to change it — and just use a simpler, straight forward, opinionated solution.

    You never intend to change it until you do. The framework is just what you need until it isn’t. One thing that I took away from POODR was the idea of using dependency injection and interfaces to keep your code reusable. And no one with any serious experience with object-oriented programming disagrees, Brent included!

    What I keep coming back to is when I finally understood the reasons for dependency injection:

    I genuinely think part of the reason SOLID never clicked for me at the agency was the simple fact that we were always going to be using WordPress. […] Now that I’m working on a project—a big one!—that doesn’t have that constraint, I’m beginning to see the value even if we were staying with WordPress.

    If you know your project won’t outgrow your framework—perhaps the scope is limited by your contract or ambition—then hack away. Even if you have bigger plans, building a project tightly coupled to a framework is fine if that’s what it takes to build the cussing thing! Am I speaking for myself? Yes.

    But I was always going use WordPress… until I wasn’t.


    1. To be extra clear: as someone who typically writes code five times faster than blog posts, there’s no judgement here! ↩︎

    → 9:56 PM, Aug 4
    Also on Bluesky
  • To every senator and representative who could have done something to stop the federal rescissions package and didn’t, and especially the ones that voted for it:

    Bless your hearts.

    → 6:19 PM, Aug 1
    Also on Bluesky
  • Yeah, our tap water is that good.

    A 16 ounce can of “purely GVL” which is lightly carbonated Greenville tap water. The label is white with black text and an illustration of a rabbit.
    → 8:53 AM, Jul 31
    Also on Bluesky
  • I would like to formally thank the cancel culture participants for getting James Gunn fired by Disney in 2018. I don’t think we would have the Superman movie we do today without them.

    → 7:12 PM, Jul 22
    Also on Bluesky
  • You ever realize you’ve fallen too far down the Amazon search results?

    Screenshot from an Amazon listing. Headline is What's in the box. A single bullet point follows that simply says NO.
    → 9:08 PM, Jul 8
    Also on Bluesky
  • So I’m making a native Web Component with a library specifically for building native Web Components. Go to add it to my project… and the docs only describe adding it to a build process, not building a singular JS file I can add to my plain HTML page.

    → 11:07 PM, Jul 3
    Also on Bluesky
  • Hey, Apple? What the ‼️ is this?! Where’s the ‼️ing unsubscribe link? How do I mark this as spam?

    → 9:09 AM, Jun 24
    Also on Bluesky
  • Thinking about this:

    For where two or three are gathered in my name, there am I among them.

    And thinking of why people might be gathering right now.

    → 8:09 PM, Jun 8
    Also on Bluesky
  • Jony Ive with too much budget and too few restraints is how we got the 2016 MacBook Pro. So that’s what I’m expecting from “io.”

    → 9:19 PM, May 21
    Also on Bluesky
  • Look, mom: I’m quoted in Fast Company!

    → 8:33 AM, May 8
    Also on Bluesky
  • Had some old MIDI files from our circa-2000 iMac. For ease of use, I’d “converted” them to QuickTime movies. So naturally, they wouldn’t play today, and QT Pro doesn’t work. Shout out to Infinite Mac where I was able to load Mac OS 8.6 and convert the files back to standard MIDI.

    → 8:57 PM, May 2
    Also on Bluesky
  • Apple has been ordered to stop blocking and charging commission on links from apps to websites. Good.

    I use IAP for PillTimer; it lets me focus on the app and not payments and DRM. It’s well worth the 15% fee. But as I’ve mentioned a few times on this blog, forcing it on everyone is stupid.

    → 10:08 AM, May 1
    Also on Bluesky
  • Well I didn’t have “dentist tells me not to brush my teeth” on my 2025 bingo card, yet here we are.

    → 11:01 PM, Apr 30
    Also on Bluesky
  • “The light shines in the darkness, and the darkness has not overcome it.”

    Ergo, “while I breathe, I hope.”

    → 10:11 AM, Apr 20
    Also on Bluesky
  • In reading about Gumroad, I managed to find out that the founder is working with DOGE. That bumped up my attitude from “not angry, just disappointed” to “close my account.”

    → 6:59 PM, Apr 5
  • Bumps In the Gumroad

    It’s hard to overstate just how much my opinion on Gumroad has changed since the beginning of 2025. I’m not mad, just disappointed. Incredibly disappointed.

    Strike One: Unintended Consequences

    Let me preface this by saying I get problems with email delivery. There’s a whole system of checks and ranking that is based almost entirely on reputation. And it goes layers deep: bad behavior by one entity can risk the reputation of a provider serving thousands of people.

    So I understand why Gumroad made the change they did: sometime after December 1, 2024, Gumroad instituted a new policy: only sellers with $100 in sales could send emails:

    Screenshot from Gumroad saying You are not eligible to publish or schedule emails. Please ensure you have made at least $100 in sales and received a payout.

    A reasonable position. Gumroad provides a lot for free, and while they have a lot of features related to email marketing (which might have gotten them into trouble), it mostly exists for creators on other platforms.

    But this decision failed to consider the product holistically. See, Gumroad has another feature called memberships. Someone subscribes for a recurring fee and gets access to a pool of content that creators can consistently update, most similar to another platform that misspells “patron.” A creator can create a post on a membership, and members can comment on those posts.

    Except… for Gumroad, posts are emails. So are notifications. In fact, there is literally no other way to alert members of new content in the membership except through email. Email that is now off limits to new creators.

    This policy change hit me three months into a new membership project I was attempting. I was treating my membership product like a newsletter which—as far as I can tell—is how it’s intended to be used. I was putting out regular content and trying to build value over time. And overnight, my sole ability to connect with my customers was yanked away.

    To add insult to injury, despite the error message saying “$100 in sales,” the actual threshold was $100 in payouts. Which means the actual threshold was more like $115 in sales once Gumroad and credit card fees were taken care of.

    Now, I’ll admit that all of this is just based on my experience with the product. I’d love to link to a page documenting the change, but…

    Strike Two: This Isn’t Helping

    I couldn’t find Gumroad’s comprehensive help site. I’d previously read through it to get a feel for what was and wasn’t allowed on the site and to make sure that my plans for my project fell within scope for the platform. But now, when I needed information on a new policy, it was nowhere to be found.

    Eventually, by going to a completely separate page (payment info?) in the Gumroad admin, I stumbled upon an AI chatbot. With nothing else to lose, I asked how to send emails. It pointed me to buttons that didn’t exist. I then asked more specifically about the new policy, and it told me what I already knew. (It did not tell me about the sales v. payouts threshold.) It did provide some color as to why the policy was implemented, but it suggested building my audience organically through social media.

    Social media I couldn’t tell my customers about because Gumroad had taken away my only means of contact!

    Finally, I asked how to contact Gumroad support. It pointed me to the help site that didn’t exist and the contact form within. I eventually found an email on another page and sent a message there; the response was very obviously from the same chatbot.

    Chatbots are fine as one of many options to access support information. But as the only option? When it’s been trained on a help site that references itself (and therefore references a site that doesn’t exist)?

    Strike Three: It Doesn’t Mean That…

    I’ll admit, this one’s pedantic. But I got this email this morning:

    Screenshot from an email: Gumroad is open source! Dear Gumroad creators, Today, as we celebrate our 14th birthday, we’re thrilled to announce something big: Gumroad is now open source!

    Except… it’s not. Not technically.

    Looking at the GitHub repo, the code is released under the Gumroad Community License 1.0, a custom license. This is usually frowned upon, but not necessarily a dealbreaker for an open source release.

    What is a dealbreaker is this condition:

    You may use the software under this license only if (1) your company has less than 1 million USD (2024) total revenue in the prior tax year, and less than 10 million USD (2024) GMV (Gross Merchandise Value), or (2) you are a non-profit organization or government entity.

    This conflicts with article 6 of the Open Source Definition (emphasis mine):

    The license must not restrict anyone from making use of the program in a specific field of endeavor. For example, it may not restrict the program from being used in a business, or from being used for genetic research.

    Now, to be fair, they didn’t capitalize “open source” in the email. But the point remains: The Gumroad Community License is, by definition, not Open Source.

    Is this a big deal in the broad scheme of things? No, not really. But it speaks to how I’ve been feeling about Gumroad as a whole…

    Who Cares?

    I think what is disappointing me about this whole thing is the lack of care for the product. The changes to email causing memberships to be unusable speaks to an organization that doesn’t have someone watching over the product as a whole. These seem like short-term decisions that hurt the product’s reputation more than solve whatever problem they were intended to solve.

    For a product that I was excited to find reasons to use, this hurts. Like I said, I’m not mad; just disappointed.

    And I’d tell them to their face if they had a working support email.

    Edit: 24 hours later, I’ve closed my account. A bad product is disappointing; working with the current US administration to “cut costs” is unacceptable.

    → 10:37 PM, Apr 4
  • Today’s brainworm: a parody of “Put Down the Ducky” called “Tighten the Graphics.”

    → 9:25 AM, Apr 1
  • Sometimes I get so deep into composition and particular abstraction layers that I forget that basic object-oriented programming exists. And what I thought was going to be a nightmare to code and even more to maintain actually wasn’t that complicated. (I welcome you to tell me why it’s actually bad.)

    → 7:52 PM, Mar 25
  • I didn’t add a way to prefix Smolblog’s DB tables because I didn’t need it, and I need to not build what I don’t need.

    Today, the auto-migration wiped out my test WordPress’ tables.

    I am now building a way to prefix Smolblog’s DB tables.

    → 11:27 PM, Mar 22
  • John Gruber on the full DeepSeek AI model running locally:

    Apple has tremendous technical advantages to offer in AI. But they’re marketing Genmojis of hot dogs carrying briefcases.

    I might argue that there’s very little else to market.

    → 10:11 AM, Mar 22
  • I’m afraid—if I log out—I won’t be able to find my LinkedIn account!

    → 7:01 PM, Mar 21
  • Hey #php land, what’s going to be the easiest way to build an admin interface? I’ve got all my data persistence and retrieval functions written; just need to build the UI. (Would love if there was some easy way to build the forms in WordPress' backend.)

    → 3:24 PM, Mar 9
  • I’m thinking of making a custom language definition for highlight.js so I can specially-format parts of a story (chat window, AI dialogue, etc.) without leaving Markdown.

    Am I overcomplicating this?

    → 11:34 PM, Mar 3
  • I want to like Scrivener so much more than I do. I want to use it, really dive into it, but writing in it feels like using a word processor; anything too far from CSS isn’t intuitive for me anymore. And the HTML it generates is… generated HTML.

    So… anyone organizing a novel with Markdown?

    → 3:13 PM, Feb 23

Slightly uneven since 2005.

Find oddEvan on

  • Micro.blog
  • Bluesky
  • Mastodon
  • GitHub
  • Tumblr
  • YouTube
  • LinkedIn
  • Read.cv
  • TCGplayer

Projects

  • Smolblog
  • PillTimer
  • oddEvan UI
  • madcrasher
  • Other projects

Archive

Links

  • Blogroll
  • Resources
  • Fun Times

About

  • About Istoria

Colophon

Typeset in Raleway by The League of Movable Type and Satoshi by the Indian Type Foundry. Powered by Micro.blog. All your base are belong to us.

© Evan Hildreth; licensed under CC BY 4.0.