Gutenberg and Blocks
ACF Blocks: Build Dynamic WordPress Content
ACF Blocks are changing how WordPress developers build websites. Learn how to leverage Advanced Custom Fields to create dynamic, custom Gutenberg blocks.
In the ever-evolving landscape of WordPress development, the Gutenberg editor has revolutionized how we create and manage content. While Gutenberg offers a powerful block-based editing experience, many developers and site administrators crave more flexibility and control over their content structures. This is where Advanced Custom Fields (ACF) and its ACF Blocks feature come into play. ACF Blocks empower you to create custom, reusable content components that seamlessly integrate with the Gutenberg editor, offering a sophisticated way to build dynamic websites.
What are ACF Blocks?
At its core, an ACF Block is a custom block for the Gutenberg editor that is registered using the Advanced Custom Fields plugin. Instead of relying solely on pre-built Gutenberg blocks, ACF Blocks allow you to define your own reusable content modules. These modules can contain a variety of fields – text areas, images, repeaters, galleries, and more – giving you complete control over the data that users can input.
Think of it this way: Instead of just having a “heading” block or an “image” block, you can create an “Our Team Member” block that includes fields for a photo, name, title, and a short bio. This specialized block can then be used repeatedly throughout your site, ensuring consistency and saving significant time during content creation.
Key Benefits of Using ACF Blocks
- Reusability: Create a content module once and use it across multiple pages and posts.
- Consistency: Ensure a uniform look and feel for specific types of content.
- Flexibility: Design custom fields that perfectly match your content needs.
- User-Friendly Interface: Seamlessly integrates with the familiar Gutenberg editor.
- Developer Efficiency: Streamlines content creation workflows for non-technical users.
- Customization: Go beyond the limitations of default Gutenberg blocks.
Getting Started with ACF Blocks
To begin using ACF Blocks, you’ll need the Advanced Custom Fields plugin installed and activated on your WordPress site. ACF offers a free version with core functionalities and a paid Pro version that unlocks more advanced features, including the ability to create custom blocks. For this guide, we’ll focus on the Pro version as it’s necessary for block registration.
Step 1: Registering Your Custom Block
The process of creating an ACF Block involves registering it within your theme’s functions.php file or, preferably, within a custom plugin. This registration tells WordPress about your new block, its name, and the fields it will contain.
Here’s a basic example of how you would register a simple ACF Block for a “Call to Action” section:
// In your theme's functions.php or a custom plugin file
if ( function_exists( 'acf_register_block_type' ) ) {
acf_register_block_type( array(
'name' => 'cta-block',
'title' => __( 'Call to Action Block', 'your-text-domain' ),
'description' => __( 'A custom block for call to action sections.', 'your-text-domain' ),
'category' => 'custom',
'icon' => 'megaphone',
'keywords' => array( 'cta', 'call to action', 'marketing' ),
'post_types' => array( 'page', 'post' ),
'render_callback' => 'my_cta_block_render_callback',
'mode' => 'auto',
) );
}
In this code snippet:
acf_register_block_type()is the ACF function used to register a new block.name: A unique identifier for your block (e.g.,cta-block).title: The human-readable name that appears in the Gutenberg inserter.description: A brief explanation of the block’s purpose.category: Groups your block with similar blocks (e.g., ‘common’, ‘formatting’, ‘layout’, or a custom category).icon: The icon displayed for your block. You can use Dashicons or provide a custom SVG.keywords: Terms that help users find your block when searching in the Gutenberg inserter.post_types: Specifies where your block can be used (e.g., ‘page’, ‘post’, or custom post types).render_callback: This is a crucial function that defines how your block’s content will be rendered on the front end. We’ll look at this next.mode: ‘auto’ shows the rendered preview in the editor and switches to the field form when the block is selected. ‘preview’ and ‘edit’ lock it to one view. Either way, ACF blocks are rendered by your PHP.
Since ACF 6.0, the recommended way to register a block is a block.json file loaded with WordPress’s own register_block_type(), with ACF settings under an acf key. acf_register_block_type() still works, and the fields and render template below are the same either way.
Step 2: Creating Your Block’s Fields
Once you’ve registered the block type, you need to define the fields that users will interact with. This is done using ACF’s Field Group interface in the WordPress admin. You’ll create a new Field Group and set its Location rules to display when the block is an ACF Block of a specific name.
For our “Call to Action” block, we might create fields like:
- Headline: Text Field
- Subheading: Text Area Field
- Button Text: Text Field
- Button URL: URL Field
- Background Image: Image Field
Step 3: Rendering the Block’s Content
The render_callback function we specified during registration is where the magic happens. This PHP function is responsible for outputting the HTML for your block based on the data entered by the user.
Let’s define the my_cta_block_render_callback function that corresponds to our registered block:
// In your theme's functions.php or a custom plugin file, after the registration
function my_cta_block_render_callback( $block ) {
$headline = get_field( 'headline' );
$subheading = get_field( 'subheading' );
$button_text = get_field( 'button_text' );
$button_url = get_field( 'button_url' );
$background_image = get_field( 'background_image' ); // Image field set to return an array
// Optional HTML anchor set in the block sidebar
$anchor = ! empty( $block['anchor'] ) ? ' id="' . esc_attr( $block['anchor'] ) . '"' : '';
// Add custom class names
$class = 'my-cta-block';
if ( ! empty( $block['className'] ) ) {
$class .= ' ' . $block['className'];
}
if ( $background_image ) {
$class .= ' has-background-image';
}
?>
<section<?php echo $anchor; ?> class="<?php echo esc_attr( $class ); ?>">
<?php if ( $background_image ) : ?>
<div class="cta-background-image" style="background-image: url(<?php echo esc_url( $background_image['url'] ); ?>);"></div>
<?php endif; ?>
<div class="cta-content-wrapper">
<?php if ( $headline ) : ?>
<h2><?php echo esc_html( $headline ); ?></h2>
<?php endif; ?>
<?php if ( $subheading ) : ?>
<p><?php echo esc_html( $subheading ); ?></p>
<?php endif; ?>
<?php if ( $button_text && $button_url ) : ?>
<a href="<?php echo esc_url( $button_url ); ?>" class="cta-button"><?php echo esc_html( $button_text ); ?></a>
<?php endif; ?>
</div>
</section>
<?php
}
This callback function:
- Retrieves the values from the ACF fields using
get_field(). - Includes basic sanitization and escaping for security (
esc_html(),esc_url(),esc_attr()). - Constructs the HTML structure for the Call to Action section, conditionally displaying elements only if their corresponding fields have content.
- Applies CSS classes for styling, including the possibility of adding a background image.
Styling Your ACF Block
To make your ACF Block visually appealing, you’ll need to write some CSS. You can enqueue a separate stylesheet for your block within the render_callback or, more commonly, include it in your theme’s main stylesheet or a dedicated block stylesheet. Ensure your CSS selectors target the classes you defined in your render callback.
Here’s a sample of how you might style our “Call to Action” block:
/* In your theme's style.css or a dedicated block stylesheet */
.my-cta-block {
position: relative;
padding: 50px 20px;
text-align: center;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
overflow: hidden;
}
.my-cta-block.has-background-image .cta-background-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
z-index: 0;
}
.my-cta-block .cta-content-wrapper {
position: relative;
z-index: 1;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 8px;
}
.my-cta-block h2 {
margin-bottom: 15px;
font-size: 2.5em;
line-height: 1.2;
}
.my-cta-block p {
margin-bottom: 25px;
font-size: 1.1em;
line-height: 1.6;
}
.my-cta-block .cta-button {
display: inline-block;
padding: 12px 25px;
background-color: #ff6600;
color: #fff;
text-decoration: none;
border-radius: 5px;
font-weight: bold;
transition: background-color 0.3s ease;
}
.my-cta-block .cta-button:hover {
background-color: #e65c00;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.my-cta-block {
padding: 40px 15px;
}
.my-cta-block h2 {
font-size: 2em;
}
.my-cta-block p {
font-size: 1em;
}
}
Advanced Customization and Best Practices
As you become more comfortable with ACF Blocks, consider these advanced techniques and best practices:
Offering Style Options with Block Styles
Rather than building near-duplicate blocks, give one block several looks. WordPress block styles, registered with register_block_style() or a styles entry in block.json, work for ACF blocks too. A “Testimonial” block could offer “Quote only” and “With avatar” styles that share the same fields, with the chosen style arriving in $block['className'] for your template and CSS to use.
Why ACF Blocks Do Not Save HTML
ACF blocks are dynamic. The post stores the block name and its field values as JSON inside the block comment, and your PHP template renders the HTML on every request. That is why a change to the template updates every existing instance of the block at once, and why ACF blocks never show the “This block contains unexpected or invalid content” error that static blocks can.
Enqueuing Block-Specific Scripts and Styles
To keep your site performant, avoid loading all styles and scripts for every block on every page. Use the enqueue_style and enqueue_script settings in acf_register_block_type(), or the style and script keys in block.json, so the assets only load on pages that actually contain the block.
Creating Reusable Components
The true power of ACF Blocks lies in creating genuinely reusable components. Design your blocks with flexibility in mind, considering how they might be used in different contexts. This involves thoughtful field naming, clear descriptions, and robust rendering logic.
Security Considerations
Always prioritize security. Sanitize and escape all user-provided data before outputting it to prevent cross-site scripting (XSS) attacks. Use WordPress’s built-in sanitization functions like esc_html(), esc_attr(), and esc_url() diligently.
When to Use ACF Blocks
ACF Blocks are ideal for:
- Creating custom content modules like team member profiles, service boxes, testimonials, hero sections, or pricing tables.
- Ensuring brand consistency across different sections of a website.
- Providing non-technical users with a structured and intuitive way to add complex content.
- Developing custom layouts and design elements that go beyond the standard Gutenberg blocks.
- Building reusable components for client projects that can be easily deployed.
Conclusion
ACF Blocks represent a significant advancement in flexible content creation within WordPress. By combining the power of Advanced Custom Fields with the Gutenberg editor, you can build highly customized, dynamic, and user-friendly websites. Whether you’re developing for clients or managing your own site, mastering ACF Blocks will undoubtedly enhance your WordPress workflow and unlock new possibilities for your content strategy.
Need This Built for a Client?
Knowing how it works is one thing; shipping it on a deadline, under your agency’s brand, is another. That is what we do. See our white label WordPress development services, our dedicated developer plans if you need ongoing capacity, or our maintenance plans to keep client sites healthy after launch. Tell us about the project.
// related