When working in WordPress, it is common to extend the platform with Custom Fields that go beyond the default functionality. Two popular choices are Advanced Custom Fields (ACF) and CMB2.
My Preference
My personal preference is CMB2. At the same time, there are many developers I know and respect who prefer ACF and use it as part of complex and well-organized projects.
Why CMB2
I prefer CMB2 for two reasons:
- it stores post meta information the same way WordPress core does
- it encourages the practice of defining your custom fields in your PHP code
CMB2 Treats Post Meta Like WordPress Core
With CMB2, I can use the standard WordPress functions (e.g. get_post_meta()) to retrieve the information I store. This is particularly important to me because I like to make my websites resilient even when components like plugins are removed. ACF uses custom functions (e.g. get_field()) to retrieve the stored information.
If the ACF plugin is removed or deactivated, this function will not work. If you’ve wrapped your get_field()
in a check like
if ( function_exists( 'get_field' ) ) {
echo get_field( "text_field" );
}
the information will simply not display. If you’ve not included the function_exists()
check, you’ll get an error like
Fatal error: Call to undefined function get_field()
In contrast to this, since CMB2 is not used to retrieve the information if you disable the plugin, everything will still display properly.
There are some ACF users who use the WordPress core functions to directly access information stored with ACF (i.e. they use ACF to store the information but their own code to display it). I’m wary of this approach since ACF does not support this technique.
Defining Your Custom Fields in PHP Code
Version control (and more specifically Git) are an integral part of my workflow. By defining my custom fields in PHP code, I can include them in my Git repository. This makes it trivial to apply my custom fields (and any changes I make to them) to different instances of a website (e.g. I can easily apply my custom field changes to my local copy of the site, my staging copy of the site, and my production copy of the site).
While ACF allows you to define your fields in PHP code, I find that most developers I work with use the ACF interface to define their custom fields. The configuration of the custom fields created with the ACF interface get stored in the database, which is a sub-optimal place to store this configuration. ACF does allow you to export your configuration to a JSON file, which can then be imported on another machine but for my workflow this is still less convenient than defining the fields in PHP code. Again, ACF supports defining fields in PHP but their interface is so slick, I find most people define them there.
My Opinion
Once again, I want to stress this is my opinion. Choosing between CMB2 and ACF is a matter of trade-offs. For me personally, CMB2 is the better fit.
Great post Sal! One thing to note is the JSON sync feature ACF now provides. https://www.advancedcustomfields.com/resources/synchronized-json/
Good point Tim. Based on your comment, I’ve added the following line to the article. Thanks!
Totally agree with your points. The way ACF stores data is not only non-standard, but also not optimal. It stores both key and value to the postmeta table. This way, when you use ACF, you will be locked with it forever. And I simply don’t like that.
What do you think of carbon fields vs CMB2
is code based, but it’s more powerfull
you cannot do nested repeaters or flexible content like with cmb2
i am searching the best thing to include in themes and plugins
would carbon fields as clean as cmb2 ?
Hi Alexandra,
I’ve not used carbon fields so I really can’t weigh in on the pros and cons of it. I do know that you can package CMB2 with a plugin or theme. I have a write up on including CMB2 as a composer dependency but if you’re not using composer you should still be able to include CMB2 with a PHP require_once() call to load
cmb2/init.php
. WebDevStudios has an example theme that loads CMB2, which would be a good reference to checkout.Carbon Fields now supports the sort of nesting you’re talking about, @Alexandra.
ACF Does Gutenberg blocks though 🙂
Thanks.
Is there any easy way to migrate a load of ACF custom fields over to CMB2?