I’ve been a fan of Advanced Custom Fields (ACF) for a long time now. It’s used on almost every site I’ve built or worked on for the last few years.
For the unaware, ACF is a plugin that gives you more control of your content. It uses custom post meta to enrich your content with structured data. It also lets you build and configure the data fields in meta boxes when you update posts, pages, custom post types, and much more.
In the past, I’ve used the plugin as part of a project on the Delicious Brains website. However, this blog post has shown me how vital the third-party solution is for WordPress development. Let me explain…
How ACF Works
It took me a while to get my head around what ACF does, so here’s a quick example. I’ve used it on a dog rescue charity site, where users add new dogs for rehoming as a custom post type. However, along with the dog’s name, description, post title, and content, they also want to store the dog’s breed and gender, a link to a video, and some photos.
To do this, I’ve spun up a field group for this data from the Custom Fields > Field Groups > Add New menu:
You can add fields of various types. Here I’ve used selects, text boxes, a simple boolean checkbox, and a gallery field. The latter is an ACF Pro option, and I’ll discuss this some more later.
Here’s how you’d configure a select box, complete with user options:
Next, I’ve said that this group should only appear on edit screens for the Dog
custom post type. There’s all sorts of logic you can use here, such as post types, templates, categories, and user roles:
However, the real power of ACF is when you add data.
Adding Data to ACF Fields
The edit screen looks different when working on a Dog
post. It shows a custom meta box complete with the defined fields:
This makes adding all of the extra data easy for content editors. It also lets you specify exactly where you want the data to be rendered in the theme, using the get_field
function code:
<div class="columns small-12 medium-9">
<a href="<?php get_permalink(); ?>">
<h2 class="icon paw"><?php get_the_title(); ?>
<span class="dog-data">
<?php printf( ‘%s %s, get_field( 'gender' ), get_field( 'breed' ) ); ?>
</span>
</h2>
</a>
</div>
Without the plugin, I’d have to either use the default WordPress custom meta boxes, code my own richer meta boxes from scratch, or shoehorn the dog’s breed and gender into custom taxonomies. I might even have to use the native gallery embedded inside the post content. Shudders.
ACF Elevates WordPress
ACF is exactly what WordPress as a Content Management System (CMS) has been missing when it comes to having more control over your content. With over a million active installs, it has helped make the WordPress platform more powerful, and may have even contributed to its growth.
What’s more, developers and agencies have leveraged it to give clients control of their content without the need for shortcodes, page builders, or even post_content
at all. Developers have complete control over where data appears on the site’s front end, avoiding the inevitable client edits that destroy the visuals.
In fact, ACF is so popular among our customers, we had to add an integration with WP Offload Media. Now, images and cropping work with media offloaded to Amazon S3, DigitalOcean Spaces or Google Cloud Storage.
Adding Extra Field Options to ACF
The free version of the plugin has lots of functionality. However, the premium version is essential to get access to fields such as repeaters, flexible layouts, and galleries.
For example, we’re using the Repeater field to let users display select testimonials in a slider on product pages. The Repeater contains a nested post object field:
It then appears when editing the page, so we can control which testimonials will be displayed:
With actions and filters peppered around the codebase, ACF has always been an extremely developer-friendly and extendable tool. It also prioritizes improvements that are important to its users.
Using the Local JSON Feature
However, one of the few issues I’ve found in the past was storing field configurations in the database, specifically custom post types for field groups and fields.
This meant if you changed the field definition on a development site, you couldn’t push your database using a solution such as WP Migrate DB Pro back to live. You’d find the posts table would change, and you’d lose the new data.
This is the age-old database merging issue (don’t get me started…). I used to work around this by making field changes on the live site first. Then, I’d pull the database to my local site to continue with development. Not ideal.
Fortunately, ACF introduced the Local JSON feature. What this does is allow field configs to be saved as JSON files, which can sync with the database.
This awesome feature solves the database merging issue for ACF data. It also means you can keep the JSON files under version control and make the configuration a part of your typical file deployment process. While working with the plugin on our site, I added some tweaks to integrate it even more with our Git and multi-environment setup:
- I defined the JSON directory to our
app/data
directory outside of the theme (as it might change). - The “Custom Fields” menu item will only display on development environments.
- JSON files with an out of date database configuration on
admin_init
will automatically sync.
Even though we now have the WordPress Block Editor (formerly known as Gutenberg), I would argue that ACF is still vital for creating a great editing experience.
Using the Block Editor Alongside ACF
The Block Editor offers a different direction for editing content than ACF. You create content using Blocks instead of storing it as post meta data, which gives you some design flexibility.
At first, the Block Editor didn’t support meta boxes. They were even removed from the “Edit Post” screen, prompting a lot of outrage. Now, support has been added for meta boxes. They appear below the Block Editor with a minimal, less refined User Interface (UI).
Using Blocks instead of fields for custom data, the new editor has the potential to have a huge impact on ACF’s future. What’s more, new sites will be much less likely to install a third-party tool now there’s a native solution.
However, it’s not the first time proposed core changes have threatened the future of ACF. A few years ago, a new team was put together for Post Meta. At first, this sounded like it would kill off the various third-party custom fields solutions:
There have been a slew of libraries/frameworks/plugins (CMB, SCB, WPAlchemy, ACF, Pods), which have filled this role for the moment. We’ll look to these as spiritual prequels to a new core-worthy plugin.
At the time, I wrote about how this decision to introduce new competing features might make some plugins redundant. Ultimately the Post Meta project didn’t go anywhere, the new editor arrived, and ACF weathered the storm.
ACF not only bounced back, they adapted. The result was something that combined the power of ACF and the flexibility of custom Blocks. Let’s talk about this next.
How to Build Blocks Using ACF
Obviously, custom Blocks can be beneficial. However, the technical process to create them is complex. ACF Blocks fill the gap.
ACF Blocks integrate with your current custom fields, are dynamic and customizable, and let you achieve two things:
- You can take your current custom fields into the Block Editor ecosystem.
- You’re able to create custom inline solutions.
They’re rendered using a PHP template file or callback
function – so it’s just like developing a theme. They also retain WordPress core compatibility, so you could even create reusable Blocks through the framework.
While ACF Blocks aren’t a crutch, I’d say that if your React skills are still sketchy, you’ll definitely want to investigate them further. They’re going to let you leverage the power of the Block Editorwhile staying within the familiar functions.php
file.
Building an ACF Block
Let’s show you how to build an ACF Block. The Pro version of the tool has included this functionality from ACF 5.8, so it’s been with us for around two years now. Here’s the super-simple example block registration code:
add_action('acf/init', 'my_acf_init');
function my_acf_init() {
// check function exists
if( function_exists('acf_register_block_type') ) {
// register a testimonial block
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_template' => 'template-parts/blocks/testimonial/testimonial.php',
'render_callback' => 'my_acf_bock_render_callback',
'category' => 'formatting',
'icon' => 'admin-comments',
'keywords' => array( 'testimonial', 'quote' ),
));
}
}
From here, you’ll want to create a field group and render the Block. For the former, you’ll do this from within the Custom Fields > Field Groups screen within WordPress:
Here, add your field group and populate it as normal. However, in the “Location” meta box, you’ll want to use the “Block” rule to select (in this case) the Testimonial Block.
Finally, you’ll need to render the Block. This follows the same process you might already be used to with custom fields:
- Create a template file for your theme based on the parameter given in the
render_template
setting when initially registering the Block. - Choose the right method for rendering the Block.
- Enqueue your styles and scripts.
Note that the acf_register_block_type()
function offers enqueue_style
, enqueue_script
and enqueue_assets
settings.
On the whole, Blocks shouldn’t replace every custom field meta box where they’re needed, but they will let you take advantage of crafting content in the editor.
‘InnerBlocks’ Support
The Block Editor also has functionality that helps you work with ACF Blocks. InnerBlocks essentially let you insert any new Block into your ACF Block.
They can be custom or core Blocks, and you’re able to use the current “Title”, “Content”, and “Button” fields in your own ACF Blocks.
Here’s a quick tutorial to get up and running. To start using InnerBlocks, you include 'jsx' => true
in the supports
array:
acf_register_block_type( array(
'name' => 'testimonial',
'title' => __( 'Testimonial' ),
'render_template' => 'template-parts/blocks/testimonial/testimonial.php',
'mode' => 'preview',
'supports' => [
'align' => false,
'anchor' => true,
'customClassName' => true,
'jsx' => true,
]
));
You’ll then need to echo
the <InnerBlocks />
HTML tag in your Block template:
echo '<div class="block-about__content">';
echo '<InnerBlocks />';
This is only a simple example, but there’s lots more you can do with InnerBlocks.
Alternatives to ACF Blocks
Of course, ACF isn’t going to be the only solution for creating Blocks. As such, your first instinct is likely going to be a custom build.
We’ve covered how to create a ‘vanilla’ Block in the past, but before you begin, you’ll need knowledge of React.
There are also WordPress plugins that let you assemble Blocks from various components, but I’d say they’re not really for developers but ‘end-user tinkerers’. Lazy Blocks is regularly updated, so this is a good option if you want to experiment with what it offers.
The Future of ACF
Since its release, ACF has been a vital complementary plugin for WordPress. It extends, enriches, and makes the platform more usable. I don’t think I could build websites without it.
However, combining the Block Editor and ACF Blocks is the icing on the cake – it’s an excellent investment in the future of the CMS. It will help lower the barrier of entry for developers to extend the Block Editor without starting on the steep learning curve of React. In the long run, those who are pushing so hard for the evolution of the Block Editor could see this as a win.
Since the introduction of the Block Editor, what are you using to build sites? Let us know in the comments section below!