For most people, the most common workflows native to WordPress are:

  1. The Page/Post Editor.
  2. The Customiser.
  3. The Widgets area.

Without custom development and putting page-builders/paid-for themes aside, extending the native Page/Post Editor‘s functionality beyond that of the WYSIWYG has been achieved mainly through plugins, shortcodes, or Advanced Custom Fields.

Page-builders meant more complexity and bloat, which meant a slower user experience on both the backend and frontend.

Gutenberg is WordPress’s own take on a page-builder and its blocks are designed to replace plugins, widgets, and shortcodes. Even global settings like navigation menus and the site logo are roadmapped to be integrated into Gutenberg. The idea is to decrease the variation of workflows and deviation between them in order to centralise as much as possible; creating a more unified backend UX and development process.

At Twenty Eighty Online, we create custom themes through a combination of hard-coded page/post sections and ACF blocks. Hard-coded sections work well for archive or contact pages, where the addition of content to those locations is automated by WordPress with a simple blog post, for example. Blocks, on the other hand, provide flexibility if the client wants more control over specific areas of content creation and presentation. The Flexible Content filed within ACF also provides a degree of flexibility for the user but they are restricted to using only the fields made within the ACF Flexible Content field. Moving forward, we are embracing more block-based theme creation utilising, specifically, ACF Blocks.

Natively, Gutenberg has a few useful blocks that can be laid out and styled to a certain degree without any input from a developer. Going beyond that, we can now edit the theme.json file to add, subtract, and mould the native blocks to align more closely to a theme. But customisation to functionality is limited. This is where ACF Blocks come in.

There are 2 ways to approach making your own custom blocks.

  1. React Block API
  2. ACF blocks

At Twenty Eighty Online, we use only ACF blocks. I’ve been working as a WordPress developer for just over 2 years and have no prior knowledge of web programming. In my first year as a junior, I was learning mostly HTML, CSS using SCSS, and a touch of PHP but the PHP was mainly for templating purposes. Now, I use PHP mostly for creating ACF Blocks.

So, even without much knowledge of JS, I’ve been able to be fairly productive using the ACF/PHP combination. Now, I’m looking for ways to leverage the most commonly written code in a way that can speed up theme creation. We have a boilerplate at work which we all contribute to and clone for new projects. I’ve been contributing some custom block boilerplate code, recently. It made me wonder how many other developers who make ACF blocks are doing the same thing and what commonalities there might be across our collective set of custom block code.

I googled around and came across WordPress also has its own library of blocks you can check out here.

But none of these cater directly to individual clients’ needs without a degree of customisation. The whole premise of creating custom blocks is to cater for specific requirements. Depending on what you need to make, some custom blocks could well serve as templates to get started but functionality and styling may have to be either added or removed, accordingly.

This brings us to another aspect of creating custom blocks and themes in general. Creating a theme sets a baseline standard around brand design, providing clients with options for predefined colours, spacing, layout, animation, filters, fonts, and so on. But how and which of these should be editable is a nuance that is addressed on a case-by-case (or block-by-block) basis, through consultation with the client.

Okay, so when should the client have more or less control over the elements that affect the theme?

Can we distill those requirements down to the absolute basics to use as a framework to build upon?

When the output on the frontend becomes more or less predictable. For example, if a client has a hero block with an optional image background filter, then depending on whether the filter lightens or darkens the background image, the overlaying text should be editable to be either lighter or darker in order to achieve readability. So, in this case, we can supply editability of the font colour with the Colour Picker.

But what if the client wants a video background?

How do we anticipate the contrast of the video changing in degrees of lightness/darkness?

In this case, the client might ask for the text to change in brightness/darkness, automatically, in contrast to the changing brightness/darkness of the background video.

So, what would the internal process of that look like, hypothetically, for the developer?

Would that extra functionality be written from scratch or could it be extended from a boilerplate?

This is when I came up with the idea of making an ACF custom block functionality-specific boilerplate library. You could argue that finding the most common design patterns and making reusable snippets from them would be more flexible but I think having all the fundamental parts in a self-contained folder where the foundation is laid out already would be quicker, clearer, and amply extensible/malleable.

Another reason I like using blocks is because they are interchangeable with native blocks. ACF Flexible Content is flexible in the sense that a user can choose which field to add and in which order but those fields are self-contained in the parent Flexible Content field, which does not integrate well with Gutenberg because the_content() (which contains the Gutenberg blocks) is called either before or after the Flexible Content field.

Why don’t you just use ACF Flexible Content, since it’s easy enough to make custom fields that provide all the functionality of both ACF Blocks and Gutenberg blocks?

I see 2 main reasons:

  1. Using blocks allows content to be previewed from within the page/post editor.
  2. Gutenberg has a friendlier UI and UX in general.

On the other hand, I only see one reason to use Flexible Content:

  1. When making highly bespoke websites where you want to purposefully restrict/direct user editability.

Previewing ACF Blocks brings additional architectural considerations to the development of a theme. In order to make an ACF Block preview appear accurately in the page editor, we must add the hook, ‘admin_enqueue_scripts‘. It looks something like this:

// Custom Admin Style added through admin_enqueue_scripts hook
add_action( 'admin_enqueue_scripts', function() {

  // Register style
  wp_register_style( 'typography-css', get_template_directory_uri() . '/build/css/common/typography-min.css', false, '1.0.0' );
  // Enqueue style
  wp_enqueue_style( 'typography-css' );