Lessons

A Primer On Registering Blocks with ACF and block.json

Let's set the ground work and scaffold our first ACF block.


Steps in this guide:

  1. Register our blocks with block.json
  2. Handle our block data
  3. Create the block render template
  4. Using the block

Register the block

Since WP 6.0, the recommended way of registering blocks is via block.json. This is a big deal, because keeping our ACF blocks as close to Core as possible allows us to take advantage of many native block features.

You can register blocks from a plugin or your theme. For simplicity, and to make this guide more accessible to beginners, I’ll be doing this directly in my theme. Go ahead and stub out the following structure:

/theme-root

└─── /blocks
│   │   register-blocks.php
│   │
│   └─── /my-first-block
│       │   block.json
│       │   block.php
│       │   template.php

In /blocks/my-first-block/block.json, we’ll configure our block. The JSON example below is just about the bare minimum you need to register a block.

{
    "name": "my-first-block",
    "title": "My First Block",
    "description": "Displays my very first ACF block.",
    "category": "theme",
    "apiVersion": 2,
    "acf": {
        "mode": "preview",
        "renderTemplate": "blocks/my-first-block/block.php"
    },
    "supports": {
        "anchor": true
    }
}

Inside of /blocks/register-blocks.php, we’ll include the path to our block’s json file. This is where we’ll register all future blocks:

register_block_type( get_template_directory() . '/blocks/my-first-block/block.json' );

In your functions.php you can include the path to /blocks/register-blocks.php..

/**
 * Register ACF Blocks
 */
require get_template_directory() . '/blocks/register-blocks.php';

Just to recap what’s going on:

Our function.php file includes our /blocks/register-blocks.php file. /blocks/register-blocks.php will be where we register all of our future blocks by pointing to each block’s block.json.

Handle our block data

/blocks/my-first-block/block.php will serve as the model / controller for our block. It’s where we’ll handle all of the data that gets passed into the render template. This helps keep things clean and organized so our logic is in one place (block.php) and our front-end template (template.php) is in another.

<?php
/**
 * My First Block
 */

// $data is what we're going to expose to our render template
$data = array(
	'example_field' => get_field( 'example_field' ),
    'another_field' => get_field( 'another_field' )
);

// Dynamic block ID
$block_id = 'my-first-block-' . $block['id'];

// Check if a custom ID is set in the block editor
if( !empty($block['anchor']) ) {
    $block_id = $block['anchor'];
}

// Block classes
$class_name = 'my-first-block';
if( !empty($block['className']) ) {
    $class_name .= ' ' . $block['className'];
}

/** 
 * Pass the block data into the template part
 */ 
get_template_part(
	'blocks/my-first-block/template',
	null,
	array(
		'block'      => $block,
		'is_preview' => $is_preview,
		'post_id'    => $post_id,

		'data'       => $data,
        'class_name' => $class_name,
        'block_id'   => $block_id,
	)
);

$block, $is_preview, and $post_id are variables given to us by the block registration API.

$block
Contains all of the attributes of our block from the block API. We have access to the block’s name, description, ID, class names, and many other attributes that come from the block editor.

$is_preview
Either true or false – it tells us whether the block is currently being viewed in the block editor (true) or the front-end (false).

$post_id
The ID of the post or page that the block is being viewed on.

The other three variables, $data, $class_name, and $block_id are variables that we have defined ourselves.

Create the block render template

Now we can create the block’s render template: /blocks/my-first-block/template.php.

<?php
/**
 * Block Name: My First Block
 *
 * Description: Displays my very first block.
 */

// The block attributes
$block = $args['block'];

// The block data
$data = $args['data'];

// The block ID
$block_id = $args['block_id'];

// The block class names
$class_name = $args['class_name'];
?>

<!-- Our front-end template -->
<div id="<?php echo $block_id; ?>" class="<?php echo $class_name; ?>">
    <?php
        if ( $data['example_field']) {
            echo "<p>" . $data['example_field'] . "</p>";
        }

        if ( $data['another_field']) {
            echo "<p>" . $data['another_field'] . "</p>";
        }
    ?>
</div>

All of the data exposed to our block’s render template is found in the $args variable.

Up next

Once you’ve got your first block working, I’d recommend one of the following lessons next:

  1. Posts Loop Block with ACF and block.json
    Build a custom block to loop through your WordPress blog posts with Advanced Custom Fields and block.json.

  2. How To Enable Core Block Features In ACF Blocks
    Take advantage of the core block editor color picker, add margin and padding, or set custom borders on your ACF block.


🤜 🤛 You did it!

If you've followed along, let me know how this went or if you have any questions.
@Joey_Farruggio or joey@joeyfarruggio.com