Surely you can’t be serious: Does Gutenberg REALLY do this???

I’m building a pair of new WordPress sites for a client, using a base block theme I created. My plan going in was to create two child themes, one for each site. But after I finished the first site, I realized that the differences between the two were entirely cosmetic, so I thought I would use the new global style variations feature to just create one child theme for both sites to use, letting the sites have their own separate theme.json files via the styles folder in the child theme. (Let’s call them site1.json and site2.json.)

The problem is, I have a few site-specific code customizations beyond what can be handled in the theme.json file. And, more importantly, I want to hardcode which style variation each site uses. No need to muck around with the Site Editor (a.k.a. “Full Site Editing”). I do not want the client to have any access to that feature whatsoever.

So, I figured… OK, I’ll create a constant based on the domain, to tell me which site we’re on. I can use that for all of my “old school” PHP-based site-specific stuff. Now I just need to find the function WordPress uses to tell which style variation the site is configured to use.

Except… uh… I really can’t seem to do that. I googled it. I used the dreadful search tool in the WordPress Developer Reference. I checked a few of the tutorial sites. Nothing.

I even poked around the WordPress source code. Still nothing.

Finally, I rationalized… well, it has to be storing that setting in the database, so I’ll just temporarily turn on the Site Editor, set my style variation, and then search the wp_options table of the database to see where it turned up, and then maybe I can reverse engineer from that.

Nope.

There’s nothing in the wp_options table.

Oh no, I thought. They aren’t putting this into the wp_posts table, are they?

Yes, and no.

Yes they are, but no, it’s not what I thought. It’s much, much worse. They’re copying the entire contents of the style variation’s JSON file into the table.

Ugh. I mean, I kind of get why they’re doing that… because you can make additional customizations directly in the Site Editor, and that “post” (eye roll emoji — yes I have the stupid built-in WordPress emoji functionality disabled via my No Nonsense plugin) is where those changes get stored. But, uh, wouldn’t it also make sense to store the name of the base style variation itself, in case the user wants to reset it? Maybe they do — somewhere — but I’m once again too demoralized by the seeming absurdity of this whole enterprise to try to track it down.

The big problem is, this means I can’t just hardcode a way for the two sites to load a style variation’s JSON instead of the base theme.json file. And since that file is &#%^!#ing JSON instead of PHP, I can’t put conditional logic directly in it.

I’m leaving this post here, with the situation unresolved at the moment, but my next avenue will be to see if I can find a place where I can shunt WordPress over to using my variation JSON files.

Yes, I am Doing It Wrong™. But if you ask me, the entire thing is doing it wrong.

And don’t call me Shirley.


Update: OK, like, ten seconds after I published this, I decided that the correct course of action is simply to, alas, scrap my idea of using global style variations, and go back to building two separate child themes, even though it will mean a lot of redundancy. Global style variations are a good idea, but they’re just not implemented in a way that is practical for me to use. (Which makes me wonder if the way they’re implemented is really practical for anyone to use, but once again I am clearly not the core team’s target audience.) Thank goodness I hadn’t yet emptied the trash on my Mac.

More Gutenberg madness (“This block has encountered an error and cannot be previewed”)

The WordPress Gutenberg project (a.k.a. the Block Editor) is supposed to make building WordPress sites faster and… well… once you get the hang of it, that often is the case. Recently I’ve actually marveled at how quickly it has allowed me to build out a site, now that my base theme is getting a bit more polished. And creating block patterns in WordPress 6 is super slick, after you learn a few of its quirks.

But then, the Block Editor will throw me a curveball that can derail things for days. For instance, there’s this:

I have a site using my custom theme that all of a sudden started throwing out this message after a recent update. It’s on the Separator block (a.k.a. a glorified <hr> tag). I took a look at the code, and there’s nothing overly complicated going on. The best clue I had to the problem was that it may have something to do with the .has-alpha-channel-opacity CSS class getting applied to the tag.

Then I noticed that in a child theme I’m building for another site, the error didn’t occur. I tried switching between the child theme and parent theme, and sure enough — with the parent theme, I get the error; with the child theme, I don’t. So… what is it?

Well… with almost any type of problem solving, it’s about trial and error, finding differences, ruling things out, and narrowing your search. But it was really hard to find anything between the parent theme and child theme that might cause this. Certainly there were no differences in how they treat Separator blocks.

I came back to that CSS class. Why is that there? Where Gutenberg is concerned, when in doubt, it’s always a good idea to have a look at the theme.json file. And, sure enough, that’s where the difference was. In my parent theme, I had this (note line 13):


But in the child theme, I had this:


Yes, for some reason, an empty array for the color.gradients setting allows the Block Editor to properly parse the Separator block, but a null value causes the error.

WHY???

I don’t know. I don’t really care. At least I was able to fix it. But this again makes me question the wisdom of the entire Gutenberg enterprise. I still don’t really buy the rationale that this JSON file is the way to go, although I am at least starting to understand why it was chosen. However I think this example illustrates some of the negatives of the approach.

Building a WordPress block theme is shortening my life expectancy

Throughout my (now quite long) career as a web developer, I have had many ups and downs. But I have never had as many stomach aches as I have in the last year, trying to wrap my brain around a steady stream of confusing, convoluted, counterintuitive and just downright inexplicable elements of building a theme from the ground up to work with Gutenberg, a.k.a. the WordPress Block Editor.

I’ve made some major progress over the course of the year, and my theme (in various stages of completion) is now powering multiple live client sites, with development ongoing for a few more. For the most part, now, I am finally at a stage where I feel like this is the right way to use WordPress going forward, rather than just reluctantly accepting that I have no choice in the matter.

But I still feel like Gutenberg does a lot of things the wrong way — most notably in its fundamental lack of separation between content and presentation. Yes, I am going to Old Man Yells At Cloud this. I know React is the new hotness and now everything needs to be done in ES6 (which I will forever call JavaScript), but the WordPress core team is throwing away some of the platform’s greatest strengths by abandoning this core component of how it (like pretty much any 2000s-era CMS) is built.

It may seem that I’m just an old curmudgeon who doesn’t want to learn React (I don’t), but it’s not just that. It’s that every aspect of this interface that has been designed to make it easier for average users to interact with — which, I think, it finally is, 5 years after it was unceremoniously forced on us — makes the process of developing for it harder, and more abstract.

There are two unrelated but connected problems with how things are going down here.

First, modern developers just love dependencies.

I get it. To an extent. Reusing tried-and-true code libraries instead of rolling your own all the time is smart. But that means you’re using code you probably haven’t looked at closely. You don’t really know how it works. It may have bugs, or it may have opaque features you don’t realize are there, or it may just have too much stuff bloating it, slowing down performance and making applications more brittle. Pile dozens of these dependencies together, and you’ve got a lumbering behemoth of code that no one in the world completely understands. And I truly do believe we are at a point where no one, at all, knows entirely how the current version of WordPress works. On top of that, any time you’ve got external dependencies, weird things can happen.

Second, Gutenberg is evolving so quickly that the documentation hasn’t kept up.

Gutenberg’s documentation is occasionally out-of-date, always incomplete, and it’s only getting worse.

I know writing documentation is tedious, and the web has never had good documentation. When I was in college in the mid-’90s and I wanted to learn HTML, I went to the campus computing department and asked them how I could go about learning HTML. They, seriously, just told me to download BBEdit. Which I did. And which didn’t help me learn HTML at all. (Although it is still the text editor I write all my code in, 29 years later.) So how did I learn HTML? View source. Because back then, you could do that.

I don’t expect to be able to just “view source” and learn how Gutenberg works. But since WordPress is open source software, and I have the files right here on my computer, I do think that when the documentation fails me, I should be able to poke around in the source code and find what I’m looking for.

Let’s get specific. As it happens, in my theme I’m addressing one of my earlier complaints above by using ACF Blocks. It’s been a rough road, but I’m starting to make really good progress. The only problem is, my styles aren’t getting applied. My CSS for the block isn’t loading in the Block Editor, and the Block Editor styles I’ve configured my block to support (colors, spacing, typography) via its block.json file are not showing up on the front end.

Well, what do I do about that?

Focusing on the front end first, I know that Gutenberg’s styles get applied courtesy of pithy CSS class names like .has-primary-background-color as well as HTML style attributes using CSS variables, like var(--wp--preset--spacing--80).

But if I look at the block attributes in the Block Editor’s comment tag, or the JSON or PHP array of style properties for the block, I see the same is formatted as such: var:preset|spacing|80

The quarter century of development experience in my old fart brain tells me that there must be a function or method, somewhere, that converts var:preset|spacing|80 into var(--wp--preset--spacing--80), and that I would be better off trying to find that function than writing my own.

Uhhh… OK. So how do I go about that?

ACF’s documentation for this feature is abysmal, which is kind of understandable, since the whole thing is a moving target that is changing rapidly (not to mention the organizational challenges that happen when the company that bought you out gets bought out itself), and the core WordPress documentation isn’t much better. So I’m left resorting to a scavenger hunt through the WordPress code. But it’s layer upon layer of 5-line functions referencing each other through a series of add_filter() callbacks.

As usual with my Gutenberg rants, I don’t have any solid conclusions to end on here. This whole post was mostly an exercise in working out that knot that was gnawing at my insides. At least I’ve done that. But I’m no closer to solving my problem. That’s probably because the real problem isn’t what I think it is. And it’s not going away.

All I know is, building a block theme — at least, for me, right now — takes way longer than building a classic theme. And I think that’s because my approach, one developer just cranking away, is not the model anyone in the core WordPress development community cares about, or possibly even comprehends existing. These days I’m not extremely confident about its continued viability myself.


Post script: I think I actually managed to find it, by using BBEdit’s multi-file search on this string: '|'

The method is: WP_Theme_JSON::get_property_value()

Of course, that doesn’t get called directly. It’s called in WP_Theme_JSON::compute_style_properties() which is in turn called by WP_Theme_JSON::get_block_classes() which itself is in turn called by WP_Theme_JSON::get_stylesheet() and then we’re getting too far afield, because that’s used to turn the theme.json file into inline CSS.

So I am guessing at this point that I probably should not use any of these methods. (Actually, I can’t because they’re all protected.) It really seems like this should be happening automatically, and either ACF Blocks are missing some key functionality, or I’m missing something about how ACF Blocks work (which I would blame on the lack of documentation).


Update (April 11, 2023): After I wrote this blog post, I also started a thread on the ACF forum, and there I was finally given an answer. Yes, there is a WordPress function for getting block wrapper attributes. It is even, um, named exactly what it should be. But as the fellow ACF user who responded with that enlightening bit of information even noted, it is incredibly difficult to find. The WordPress documentation does, to its credit, include most if not all (I mean, how would I actually know?) functions and methods, but the search tool is a joke.

Quick CSS fix for WordPress Block Editor (Gutenberg) link hover color issue

The WordPress Block Editor (a.k.a. Gutenberg) makes it easy to set the text, background, and link colors on any block. But links can and often do have more than one color. And there’s no option here for setting the hover color. So what do you do in what, I think, may be a common situation, where you’re setting a background color on a block and making the link text white, but your theme’s link hover color is either the background color you’re switching to, or something way too close to it?

I’ve come up with a very tidy bit of CSS code that will make your link hover state match the custom link color — granted, you lose the UX of a unique color on hover state, but you gain necessary legibility and accessibility, which I guarantee is more important.

This may not work in every situation, but it’s so simple that it’s worth investigating as an option. With this code, any time you have a block that sets both a custom background color and a custom link color, it will ensure that the hover/focus state matches the custom link color:

main .has-background-color.has-link-color a:focus,
main .has-background-color.has-link-color a:hover
{ color: inherit; }


Update (April 4, 2023): Yeah, don’t do this. You can specify these colors in theme.json. I’m not sure if this is a recent addition, the documentation was previously lacking, or I just didn’t find it, but anyway… do this instead.

This is the kind of thing that I find maddening about Gutenberg

First off, if you are the regular reader of this blog, you are painfully aware of how much I am waffling on rejecting or embracing Gutenberg (a.k.a. the WordPress Block Editor). There are things I genuinely do like about it, but I also have some fundamental disagreements with its approach (like the facts that it writes inline CSS directly into post content, or that its templates don’t support PHP code).

And then there are the weird little quirks that just make using it much more difficult than it needs to be. In general I have learned that this comes down to the incredible finickiness of JSON. Fine. But the fact that one character out of place in the theme.json file can break everything seems a bit ridiculous… or at least, a big step backwards for usability.

Fix your syntax. Sure. I wish JSON allowed trailing commas the way PHP — and even JavaScript! — does, but I can grok the fact that it doesn’t and learn to adapt. What I have a bit more trouble with is the problem that struck yesterday, only because it was so hard to pin down.

I’m working on a new, small block theme as a one-off for a unique project — a website that will feed menu board monitors in a pizza place. Seems like a perfect opportunity to practice and experiment a bit with what Gutenberg can do. (And, after over a decade of trying to find the “right” way to give restaurant staff a reliable but still easy-to-manage web interface for updating menu information, I actually think Gutenberg’s Block Patterns might be the optimal solution.)

So here’s the maddening thing. I was setting up my theme.json file like a good Block Theme developer, defining all of my colors, typography, etc. And then I started loading in some test content. All looked fine on the back end, in the Block Editor itself. But none of the styles were getting applied on the front end!

I googled the problem, of course, and found a WordPress forum thread about this very issue.

Huh. Sure enough, what’s described in the thread was exactly what was happening in my case. I had this line in my code (font names changed to protect the innocent):

"fontFamily": "'Helvetica Neue', 'Comic Sans', 'sans-serif",

Do you see the problem there? (No, it’s not the trailing comma… that actually belongs, in context.) It’s the stray apostrophe before sans-serif. Removing that fixed the problem.

Now, if this were just in straight CSS, I would have seen the problem immediately, because the syntax highlighting in BBEdit would’ve gone all wonky. But since this was inside a text string in JSON, it looked just fine, and I didn’t notice the apostrophe was there.

I get that the parser that converts the contents of theme.json into CSS would get thrown off by this. Honestly, I’m surprised it didn’t cause the whole page to bork with a PHP fatal error… I’m pretty sure earlier versions did throw a fatal error if there was any problem parsing the theme.json file. So this is… an improvement?

I also get that the generated CSS output would not work properly. What I don’t get is that it all looked correct in the Block Editor. Why was the Block Editor on the admin side able to “fix” this issue, but on the front end it didn’t? It doesn’t make sense!

Anyway, trying to unravel that mystery wasted about an hour late yesterday afternoon, when I was finally starting to get productive after having a near existential crisis over Gutenberg for most of the week.

These are hard times to be a WordPress developer. No, strike that. These are hard times to be a generalist web developer who happened to make the fateful decision 8 years ago to go all-in on WordPress.