WordPress Gutenberg Editor Optiongeddon, Controlling the Uncontrollable

thisbit
9 min readApr 13, 2022

--

View from inside of Chernobyl power plant control room, showing a complex Interface to operate the Reactor.
“Chernobyl continues to employ many workers” by bbcworldservice is marked with CC BY-NC 2.0.

This post is a part of the series about building a website Design System with GeneratePress and GenerateBlocks focused on enforcing such a system on a mid-size editorial team. Controlling the Gutenberg Block Editor is an (unnecessarily) complex problem. I will break this problem into two posts: the one you are reading right now will be a diagnostic part, exploring the state of affairs, so to speak, and the second will present a solution I came up with for a specific use-case, primarily based on GeneratePress and GenerateBlocks tools.

As one develops the front-end, one has to think about the back-end experience for the editorial team. Right? In a larger team with a variety of tasks/skillsets, thinking about the back-end experience is also a question of whether the style guide gets followed or not. Debates in the WordPress space over what clients should be able to do on a website are many. They span from the ones arguing for total control over the design to a hippy approach where UI should set free the client’s creativity. Latter probably being the attitude Matt & Matias take on this topic. 😊

What is the “state of the word” in this regard?

Since we have the block editor, once pretty straightforward problem became much more complicated. This is the case with most builders, and in some sense, builders are fundamentally about options … not limitations. It is no wonder then it is not easy to implement the controls properly, especially since (as far as I see it) the Gutenberg devs do not see this as a priority.

Whitelisting block types with the Allowed Blocks method

WordPress PhP code snippet showing core blocks whitelisted for use.

This approach was available from the very beginning of block editor being WP default. It is PHP, so we can easily hook into the “old WordPress” and limit based on User Role, Post Type, or similar. But only core blocks can be in the allowed blocks array! So if you are using anything else, and who is not, this is definitely not enough.

Disabling block type settings with theme.json

Though controls over access to stuff in the block editor are not its primary interest, theme.json brings ways to set defaults and hide some block settings from the editor. This is great, but theme.json misses two fundamental features to do this properly: it does not talk to User Groups (same settings for everyone) and does not talk to media breakpoints (same settings for all devices). Oh, and it does not work with non-core blocks.

A view of WordPress json code snippet showing various style controls turned off for the editor.

A removeEditorPanel, unregisterBlockStyle, unregisterBlockType or the JS part of the block editor API

As block editor is all JavaScript, one would expect this to be the most versatile approach to controlling the editor. But it is not. First, it does not speak to User Roles and Post Types other than not loading the js file based on these conditions. So, going back to PhP to achieve this. Second, it deregisters the blocks, so they become unavailable to other users regardless of whether the script that does this is loaded for them or not, or better yet, produces an error. Also, it does not work consistently across panels of core blocks, let alone the third party. I use this the least. If theme.json fails to control a block pannel, I use this if it works.

A WordPress JavaScript code snippet view, showing methods to unregister block types and block type styles.

Predesigned sections with core Block Patterns

Since I will be using the GeneratePress and GenerateBlocks set of tools, I will be relying on Local Templates and Global Styles to achieve what patterns try to do. Since Blocks Patterns are used to set up a composite of blocks into a piece of layout, and I will be using GenerateBlocks to build these layouts, it makes sense to make these with Local Templates instead. Also, I see them as more versatile.

This is how you disable Block Patterns altogether.

A view of WordPress PhP code snipped disabling core Block Patterns entirely.

If you want to use core Block Patterns to build your pre-made sections, you might want to hide the bloat that comes with WordPress preinstalled. There is a bug that brings back the default Blocks Patterns even after you removed them, the moment you create your Custom Pattern. A function made by the GeneratePress user patches this bug. Get the code here.

As I explored Block Patterns I have put together a plugin that creates a Custom Post Type for managing and creating Block Patterns. It is a simplified version of another plugin, integrating as well the disabling of default patterns and the bug fix mentioned above. Get the plugin here.

Using Templates and Template Lock to prevent unwanted design modifications

A view of WordPress PhP code snippet, creating a structure for a block based template with only one core/paragraph block in it, and with all changed locked for editing.

This feature is pretty nice. I have used it for an artist portfolio site I made in 2018 (I think) when block editor came out, and it works pretty nice still. However, it has some drawbacks. The currently available options are lock all and lock insert. This means one can either have everything locked, nothing locked, or have adding blocks disabled but allowing them to be shuffled. Here is a feature request for additional options. The new block-level lock feature is something yet to be explored by me. There is a way to add more flexibility to template lock if a section that one wants editable is placed in a block such as core/group and set template lock to false for this block. Inside the group block, one can edit, add, remove … More about this method here.

There are two reasons I decided not to use this. Most important is how Gutenberg templates handle changes down the line. If you have a bunch of content controlled via a template and decide to add a new block to it, it can throw a block render error in the posts controlled by that template. For simple blocks, the editor can fix the error, but for more complex ones, it cannot. This is a deal-breaker for me. Especially since GeneratePress has the Element modules to solve the same problem without the limitations of the template lock. However, it is probably the most exciting thing in core Gutenberg. So I will definitely use it at some point.

What about GeneratePress and GenerateBlocks?

By default, the GeneratePress Elements are available to admins only, so that is nice. Templates can be set to base the content on dynamic data with ACF or a similar plugin and not worry about users messing up the templates themselves. If static templates without much control from client side is needed, this is probably the solution you need.

GenerateBlocks have responsive features that can be set, so that is good. The GeneratePress & GenerateBlocks team provides us with a way to set the default styles for blocks programmatically. This is similar to what can be done to core blocks via the theme.json. Here are some of the things one can set.

Set GenerateBlocks default spacing

The spacing defaults can be set to match your design and your coding style. One can set default units and the values for this.

A view of GenerateBlocks PhP code snippet setting spacing values for GenerateBlocks Container type.
Set GenerateBlocks spacing
A view of GenerateBlocks PhP code snippet setting style values for GenerateBlocks Button type.
Set GenerateBlocks styles
Set GenerateBlocks custom breakpoints

Explore further

Find out more about these methods in this forum discussion and here. The list of all definitions on GenerateBlocks GitHub is here. Discussion about default styles definition is here, and the one about setting breakpoints is here.

These default settings do not prevent users to modify the values, but if they do not change them, the settings will have values that align with your design by default. Also, since it is PHP, it is probably possible to set different values for block default spacing and styles depending on whether it is mobile or desktop using wp_is_mobile() as a condition for these values.

Predesigned sections with Local Templates and Global Styles

Global Styles Overview

WordPress Block Editor view, GenerateBlocks Global Styles custom post type view.
A view showing grid part elements handled by Global Styles feature.

Global styles are GenerateBlock’s way to set block style globally rather than locally. They do so via CSS by allowing one to create a class for a block. Based on CSS, Global Styles are limited by this. For example, inline icons cannot be set as part of Global Styles. Global Styles are really useful for achieving consistency while providing variety via variants. For example, a version of the outlined button and a button with a fill color. Also, when global style gets updated, all instances of it get the update. However, I have at least two problems with them. They are not the default way to set styles per block type but have to be enabled. Two, they cannot handle more complex settings or do not work with more complex, compound blocks/sections as they are simply CSS styles.

Local Templates Overview

A view showing WordPress block editor with GenerateBock library Local Template inserter in focus providing various predesigned sections only.
Local Templates available options

Local templates are GenerateBlocks take on Block Patterns. They also come with premade Templates provided by the vendor, but if you do not want them, there is a toggle available only to admin. It’s that simple. Local Templates are Custom Post Types, so there is a distraction-free environment in which you can have them made and stored. They are available to users via a Local Template Library Block in the Block chooser in the editor. Custom Post Type UI is again, available only to admins.

However, a change in the Local Template does not apply to all instances. Local Templates are available from the block editor only to users who have access to GenerateBlocks themselves. One cannot make only Local Templates available to non-admin users. They come with GenerateBlocks available too. The good thing is that in combination with block defaults, and Global Styles, Local Templates are pretty close to what I need. With GenerateBlock’s powerful settings, Global styles, and a bit of JS, Local Templates can serve as a simple form of a Block Builder, allowing one to make an accordion block, for example.

Recap

A React developer can probably control much more of core blocks access and settings. I am not a react developer, so I need a method to control access to block types and block type settings based on usual conditions such as user groups, capabilities, post types, etc. My general disagreement with the block editor approach is that it promotes local design edits rather than global ones. The only part of Gutenberg that does not do this is Reusable Blocks. In my view, this should be the default. Design/style changes should be global by default, overrides should be made consciously, and there should be roadblocks to warn you of where you are heading. Variations of design should be handled with variants, such as button block has, for instance (outline and fill variants). This remark goes to GenerateBlocks as well, global styles should be the default, and local styles should be at least a toggle away.

My approach

In the next post, I will present my implementation of guardrails for a design style guide for a particular website with particular needs. What is your approach? What do you use?

--

--

thisbit

I branch into visual arts, visual communications, web dev, and teaching. Here I write about UX/UI and web dev mostly. YT https://tinyurl.com/24784589