Getting started#
Install ACF Chef, put a definition in PHP that WordPress loads, and give the field group a location rule.
You do not need to choose a special bootstrap file. You do need to hand the finished group to ACF yourself: ACF Chef declares field groups, and never adds hooks on your behalf.
Requirements#
ACF Chef requires:
- PHP 8.4 or newer
vinkla/extended-acf^15.0- Advanced Custom Fields installed and active at run time
The free ACF plugin supports most of the field types ACF Chef exposes, including the group field.
ACF Pro is required for:
- Repeaters
- Flexible content
- Layouts inside flexible content
- Galleries
The example on this page uses only fields available in the free plugin.
Install the package#
Install ACF Chef with Composer:
composer require mindfullsilence/acf-chef
Composer installs its extended-acf dependency with it.
Declare a field group#
Put the definition in any PHP file that runs during a normal WordPress request.
That could be:
functions.php- A file required from
functions.php - A plugin’s main file
- A file required by a plugin
- A Composer-autoloaded class that your theme or plugin invokes
There is no package-prescribed bootstrap filename.
use AcfChef\Chef;
add_action('acf/init', function () {
Chef::group('hero', function ($group) {
$group
->text('title')
->textarea('summary')
->location('post_type', 'page');
})->register();
});
The group name is hero, so ACF Chef derives the title Hero.
The fields are named title and summary. Their labels are derived as Title and Summary.
The location rule tells ACF to show the group when the current post type is page.
Load a page editing screen in WordPress and the field group appears there.
Registration is yours#
Chef::group() builds the field-group object and returns it. It adds no hooks, compiles nothing, and tells ACF nothing.
register() is what reaches ACF. It compiles the group and calls acf_add_local_field_group(), returning the array it registered.
$hero = Chef::group('hero', function ($group) {
$group
->text('title')
->location('post_type', 'page');
});
// Nothing has reached ACF yet.
$registered = $hero->register();
Call register() when ACF is ready for local field groups. That is acf/init:
add_action('acf/init', function () use ($hero) {
$hero->register();
});
Declaring and registering in the same callback is the shortest form, and the one the example above uses.
Two things follow from registration being a separate call.
A group can be modified after it is declared and before it is registered — which is how a parent theme ships a definition a child theme adjusts. See Finding and editing fields.
A definition can also be declared where there is no WordPress at all. Unit tests and command-line tooling build a group and read toArray() without ACF, WordPress or a hook anywhere in sight.
Register extensions before compilation#
Custom field types, cursor macros and configuration shorthands are read when a group compiles, not when it is first declared.
This means a group may be declared before the file that registers a verb it uses, provided the registration still runs before anything calls register().
Register extensions at load time:
- At the top level of a plugin or theme bootstrap file
- In a
plugins_loadedcallback
Do not leave them until acf/init.
A registration placed in one acf/init callback is order-dependent against a group compiled in another. The group may compile before that callback teaches the registry about the custom field type, macro or shorthand.
The rule is:
Declare groups wherever they read best. Register field types, macros and shorthands during application loading, before
acf/initregisters anything.
The extension pages cover the individual registration APIs:
Next steps#
Read How it works to understand what ACF Chef stores during declaration and what it creates during compilation.
The remaining pages build on that distinction.