Creating Custom Gutenberg Blocks with ACF: A Simple Guide

With the rise of the Gutenberg block editor in WordPress, developers have a powerful way to create rich, modular content. However, building custom blocks using React can be complex for many PHP developers. Fortunately, Advanced Custom Fields (ACF) Pro offers a simpler way to register and manage custom blocks using PHP.

In this post, I’ll walk you through creating a custom Gutenberg block for displaying team members using ACF’s acf_register_block_type() function. This approach allows you to build dynamic blocks with custom fields, enabling content editors to easily manage complex content without coding.


Prerequisites

  • WordPress 5.0+ (Gutenberg-enabled)
  • ACF Pro plugin installed and activated (required for block registration and repeater fields)

Step 1: Create an ACF Field Group

In your WordPress admin:

  1. Go to Custom Fields > Add New
  2. Create a field group named Team Member
  3. Add these fields:
    • member_name (Text)
    • member_position (Text)
    • member_photo (Image)
    • member_bio (Textarea)
  4. Under Location, set Block is equal to team-member
  5. Save the field group

This setup associates the fields with the custom block you will register.


Step 2: Register the Block with PHP

Add this code to your theme’s functions.php or a custom plugin:

function register_team_member_block() {
    if (function_exists('acf_register_block_type')) {
        acf_register_block_type(array(
            'name'              => 'team-member',
            'title'             => __('Team Member'),
            'description'       => __('A custom block to display a team member.'),
            'render_template'   => get_template_directory() . '/template-parts/blocks/team-member.php',
            'category'          => 'formatting',
            'icon'              => 'groups',
            'keywords'          => array('team', 'member', 'staff'),
            'mode'              => 'edit',
            'supports'          => array(
                'align' => false,
                'mode' => false,
            ),
        ));
    }
}
add_action('acf/init', 'register_team_member_block');

This registers a new Gutenberg block named “team-member” linked to your ACF fields.


Step 3: Create the Block Template

Create the template file at template-parts/blocks/team-member.php:

<?php
$name = get_field('member_name');
$position = get_field('member_position');
$photo = get_field('member_photo');
$bio = get_field('member_bio');
?>

<div class="team-member-block">
    <?php if ($photo): ?>
        <div class="team-member-photo">
            <img src="<?php echo esc_url($photo['url']); ?>" alt="<?php echo esc_attr($name); ?>">
        </div>
    <?php endif; ?>

    <div class="team-member-info">
        <?php if ($name): ?>
            <h3><?php echo esc_html($name); ?></h3>
        <?php endif; ?>

        <?php if ($position): ?>
            <p><?php echo esc_html($position); ?></p>
        <?php endif; ?>

        <?php if ($bio): ?>
            <p><?php echo wp_kses_post($bio); ?></p>
        <?php endif; ?>
    </div>
</div>

This template pulls the field data and outputs the member’s info.


Optional: Supporting Multiple Team Members with Repeater Field

If you want to allow multiple team members in one block:

  • In ACF, create a Repeater field team_members
  • Inside the repeater, add subfields for member_name, member_position, member_photo, and member_bio
  • Adjust your block registration and template to handle the repeater:

Block Registration

acf_register_block_type(array(
    'name'            => 'team-members',
    'title'           => __('Team Members'),
    'render_template' => get_template_directory() . '/template-parts/blocks/team-members.php',
    'category'        => 'formatting',
    'icon'            => 'groups',
));

Template team-members.php

<?php
$members = get_field('team_members');

if ($members):
    echo '<div class="team-members">';
    foreach ($members as $member):
        ?>
        <div class="team-member">
            <?php if ($member['member_photo']): ?>
                <img src="<?php echo esc_url($member['member_photo']['url']); ?>" alt="<?php echo esc_attr($member['member_name']); ?>">
            <?php endif; ?>
            <h3><?php echo esc_html($member['member_name']); ?></h3>
            <p><?php echo esc_html($member['member_position']); ?></p>
            <p><?php echo wp_kses_post($member['member_bio']); ?></p>
        </div>
        <?php
    endforeach;
    echo '</div>';
else:
    echo '<p>No team members found.</p>';
endif;
?>

Conclusion

Using ACF’s acf_register_block_type greatly simplifies Gutenberg block development for PHP developers by leveraging familiar ACF fields to manage content within blocks. This method improves editor usability and ensures content consistency without the overhead of React-based block development.

Try building your own blocks with ACF to unlock powerful, flexible content editing in WordPress!