Using Advanced Custom Fields to build Gutenberg Blocks

Like it or loathe it, Gutenberg is here and we’re rolling it out on client sites. But did you know you can use the excellent Advanced Custom Fields plugin to build reusable blocks that can be called from the Gutenberg editor? We’ll show you how…

James Humphreys-White

Creative Director

What is Gutenberg?

Gutenberg is WordPress’ new block-based page and post editor. Gone is the TinyMCE editor of yore and instead is a responsive, fast and easy to understand React-powered Javascript page editor.

You add blocks like headings, paragraphs, images and so on and modify those block properties with context-specific menus. Much cleaner, much simpler, and a more accurate representation of what you will see on the final page.

What is Advanced Custom Fields?

We have a developer license for this gem (ACF) and use it in every site we code. We’re talking about the PRO version here, ymmv if you are on the standard version. It allows you to add custom meta boxes that are shown in rule-based scenarios, e.g. on custom post types, specific pages by name, posts within a category and so on. It’s a game changer and turns WordPress into a true CMS. You don’t need ACF to build context-specific metaboxes but it saves hours of time in development. A brilliantly simple API gives you access to your meta data which is generally stored in the wp_post_meta table.

How does ACF work?

Say you have a team_member custom post type. Each staff member has an entry there and you use wp_query() to show them on the meet the team page. What if you have some structured data for each staff record that you need to be in an identical format for each person? This is where ACF shines. You can add fields for their job title, job description, even email for contact, and those meta fields will only be shown on the post editor page when you are on the team_member custom post type.

This works brillianty when you need to have the same, identically structured data that needs to be consistent across every record. How is that helpful with something dynamic, that changes between posts like a content editor?

Using ACF in the content editor

Clients love options. You want to give them exciting layouts but you can’t expect them to battle with shortcodes or mess around with HTML and CSS. By marrying ACF and Gutenberg, you can develop reusable blocks that’s can be used one or more times in the same or across multiple posts. These could be testimonials or layouts like an introduction where the Heading and subheading are on the left, block text on the right and the whole thing collapses to a single column on a small screen, as in the image below:

Complex layouts can be achieved using custom fields in reusable blocks on the Gutenberg Editor

Registering Block Types

First off, we need to ensure Advanced Custom Fields is active and up to date. Now we need to register our first block type.

We use the awesome Roots Sage WordPress starter theme which requires us to properly namespace our functions and classes. We also check to ensure ACF is installed and running. This goes into your functions.php file, or better yet a blocks.php partial invoked by functions.php so functions and hooked actions and filters are segregated according to their purpose.

add_action('acf/init',  __NAMESPACE__ . '\\register_blocks');

function register_blocks() {
// check function exists
if( function_exists('acf_register_block') ) {
	// register an introduction block
	acf_register_block(array(
		'name'              => 'introduction',
		'title'             => __('Introduction'),
		'description'       => __('A Introduction block.'),
		'render_template' => get_template_directory() . '/views/blocks/content-introduction.php',
		'category'          => 'layout',
		'icon'              => 'admin-comments',
		'mode'              => 'preview',
		'keywords'          => array( 'introduction', 'layout' ),
        'post_'
    ));
}
}

Set up the ACF block

Now, we set up all the fields we want the ACF block to have. Instead of assigning this Field Group to a post or page, we’re assigning it to a block! We simply choose the name of the block we registered in the last step.

Now if you go to a Gutenberg editor page and choose the new “Introduction” block it will appear and you can see the fields; however nothing will be shown in preview on the backend or at all on the frontend. That’s because we need to create a template to display the code for this block.

Creating the template

'render_template' => get_template_directory() . '/views/blocks/content-introduction.php',

Remember the render_template parameter when we registered the block? This tells WordPress and ACF that the template to render the block is views/blocks/content-introduction.php – let’s take a look at that file.

<?php
/**
 * Block Name: Introduction
 *
 * This is the template that displays the introduction block.
 */

  $heading = get_field('heading');
  $subheading = get_field('subheading');
  $rightText = get_field('text');
  $defColor = get_field('default');
  $customColor = get_field('color');

  if($defColor): $colorClass = "Default"; endif;

  // create id attribute for specific styling
  $id = 'introduction-' . $block['id'];

  // create align class ("alignwide") from block setting ("wide")
  $align_class = $block['align'] ? 'align' . $block['align'] : '';

?>

<section id="<?php echo $id; ?>" class="acf-block introduction <?php echo $align_class; ?> <?php echo $colorClass; ?> grid-x grid-container heading_and_text flex_layout align-middle mar-y3">
  
  <div class="cell small-12 large-6 left text mh500" <?php if($customColor): ?>style="background-color:<?php echo $customColor; endif;?>">
    <h2 <?php if($customColor): ?> style="color:white;" <?php endif; ?>><?php the_field('subheading', $post ); ?></h2>
    <h3  <?php if($customColor): ?> style="color:white;" <?php endif; ?>><?php the_field('heading', $post ); ?></h3>
  </div>
  
  <div class="cell small-12 large-6 right text mh500">
     <?php echo $rightText ?>
  </div>

</section>   

Essentially, we have a PHP block that assigns the ACF fields to variables. We then have our section element with various classnames to control layout. We have a default colour tick box that, if unticked, allows the user to set the background colour of the introduction hero box.

On the back end we can see our fields filled out…
Whilst on the front end, we can see the rendered block.

But what about styles?

Styles for each block can be added programatically using wp_enqueue_style(), however since these form the fundamental layouts for a site we’re building for the customer I’m content to build the styles directly into our main stylesheet which we write in SASS and compile for production when we go live. Otherwise you could be left with multiple CSS files being loaded for different blocks, something even with http2 and multiple concurrent downloads I’m keen to avoid.

So why is this so great?

Having the ability to create reusable blocks in the content area is a huge time saving, giving you the ability to create layouts for customer sites much more quickly than building native Javascript-powered blocks. Not every client has the budget to be pouring days of dev time into React-powered Javascript layouts; this gives a shortcut to use existing tools most devs already use to power some versatile technologies faster than ever before.

It’s useful for creating custom layouts, or you may want to allow people to add a testimonial in a pre-determined format, or a nice graphical element like a “Save the Date” reminder. You pull in structured data through ACF’s simple field editor and output the results cleanly and consistently on the front end.

ACF is awesome and would make our development time so much longer if it didn’t exist! Now with Gutenberg it’s a perfect match and another reason that the WordPress stack is so powerful.

Like what we have to say?

Signup for our mailing list

Scroll