Skip to content

Register advanced custom fields with object-oriented PHP


Notifications You must be signed in to change notification settings


Repository files navigation

Extended ACF

Extended ACF

Register advanced custom fields with object-oriented PHP.

Extended ACF provides an object-oriented API to register groups and fields with ACF. If you register fields in your theme, you can safely rely on version control when working with other developers. Oh, you don't have to worry about unique field keys.

Build Status Monthly Downloads Latest Version


Require this package, with Composer, in the root directory of your project.

composer require vinkla/extended-acf

To install the Advanced Custom Fields Pro plugin, download and place it in either the plugins or mu-plugins directory. After that, activate the plugin in the WordPress dashboard.

Learn more about installing ACF PRO using Composer.


To register a new field group, use the register_extended_field_group() function. This extends the default register_field_group() function from the ACF plugin. The key value is appended to field groups and fields. Here's an example of a field group.

use Extended\ACF\Fields\Image;
use Extended\ACF\Fields\Text;
use Extended\ACF\Location;

add_action('acf/init', function() {
        'title' => 'About',
        'fields' => [
        'location' => [
            Location::where('post_type', 'page')


For detailed information on field group settings, please consult the official ACF documentation. You can also find more examples in the examples directory.


All fields, except the clone field, have a corresponding class. Each field needs a label. If no name is specified, the label will be used as the name in snake_case. The name can only contain alphanumeric characters and underscores.

use Extended\ACF\Fields\Text;

Text::make('Title', 'heading')
    ->helperText('Add the text value')

Most fields have the methods default, required, and wrapper. The basic fields also have the methods prepend, append, placeholder, readOnly, and disabled. Please also check the non-standard methods mentioned in the non-standards section.


Email - The email field creates a simple email input.

use Extended\ACF\Fields\Email;

    ->helperText('Add the employees email address.')

Number - The number field creates a simple number input.

use Extended\ACF\Fields\Number;

    ->helperText('Add the employees age.')

Password - The password field creates a simple password input.

use Extended\ACF\Fields\Password;

    ->helperText('Add the employees secret pwned password.')

Range - The range field provides an interactive experience for selecting a numerical value.

use Extended\ACF\Fields\Range;

    ->helperText('Add the employees completion rate.')

Text - The text field creates a simple text input.

use Extended\ACF\Fields\Text;

    ->helperText('Add the employees name.')

Textarea - The textarea field creates a simple textarea.

use Extended\ACF\Fields\Textarea;

    ->helperText('Add the employees biography.')
    ->newLines('br') // br, wpautop

URL - The URL field creates a simple uRL input.

use Extended\ACF\Fields\URL;

    ->helperText('Add the employees website link.')


File - The file field allows a file to be uploaded and selected.

use Extended\ACF\Fields\File;

File::make('Resturant Menu', 'menu')
    ->helperText('Add the menu **pdf** file.')
    ->library('all') // all, uploadedTo
    ->minSize('400 KB')
    ->maxSize(5) // MB if entered as int
    ->format('array') // id, url, array (default)

Gallery - The gallery field provides a simple and intuitive interface for managing a collection of images.

use Extended\ACF\Fields\Gallery;

    ->helperText('Add the gallery images.')
    ->acceptedFileTypes(['jpg', 'jpeg', 'png'])
    ->minSize('400 KB')
    ->maxSize(5) // MB if entered as int
    ->library('all') // all, uploadedTo
    ->format('array') // id, url, array (default)
    ->previewSize('medium') // thumbnail, medium, large

Image - The image field allows an image to be uploaded and selected.

use Extended\ACF\Fields\Image;

Image::make('Background Image')
    ->helperText('Add an image in at least 12000x100px and only in the formats **jpg**, **jpeg** or **png**.')
    ->acceptedFileTypes(['jpg', 'jpeg', 'png'])
    ->minSize('400 KB')
    ->maxSize(5) // MB if entered as int
    ->library('all') // all, uploadedTo
    ->format('array') // id, url, array (default)
    ->previewSize('medium') // thumbnail, medium, large

Oembed - The oEmbed field allows an easy way to embed videos, images, tweets, audio, and other content.

use Extended\ACF\Fields\Oembed;

    ->helperText('Add a tweet from Twitter.')

WYSIWYG - The WYSIWYG field creates a full WordPress tinyMCE content editor.

use Extended\ACF\Fields\WYSIWYGEditor;

    ->helperText('Add the text content.')
    ->tabs('visual') // all, text, visual (default)
    ->toolbar(['bold', 'italic', 'link']) // aligncenter, alignleft, alignright, blockquote, bold, bullist, charmap, forecolor, formatselect, fullscreen, hr, indent, italic, link, numlist, outdent, pastetext, redo, removeformat, spellchecker, strikethrough, underline, undo, wp_adv, wp_help, wp_more


Button Group - The button group field creates a list of radio buttons.

use Extended\ACF\Fields\ButtonGroup;

    ->helperText('Select the box shadow color.')
    ->choices(['Forest Green', 'Sky Blue']) // ['forest_green' => 'Forest Green', 'sky_blue' => 'Sky Blue']
    ->format('value') // array, label, value (default)

Checkbox - The checkbox field creates a list of tick-able inputs.

use Extended\ACF\Fields\Checkbox;

    ->helperText('Select the border color.')
    ->choices(['Forest Green', 'Sky Blue']) // ['forest_green' => 'Forest Green', 'sky_blue' => 'Sky Blue']
    ->format('value') // array, label, value (default)
    ->layout('horizontal') // vertical, horizontal

Radio Button - The radio button field creates a list of select-able inputs.

use Extended\ACF\Fields\RadioButton;

    ->helperText('Select the text color.')
    ->choices(['Forest Green', 'Sky Blue']) // ['forest_green' => 'Forest Green', 'sky_blue' => 'Sky Blue']
    ->format('value') // array, label, value (default)

Select - The select field creates a drop down select or multiple select input.

use Extended\ACF\Fields\Select;

    ->helperText('Select the background color.')
    ->choices(['Forest Green', 'Sky Blue']) // ['forest_green' => 'Forest Green', 'sky_blue' => 'Sky Blue']
    ->format('value') // array, label, value (default)
    ->stylized() // stylized checkbox using select2
    ->lazyLoad() // use AJAX to lazy load choices

True False - The true / false field allows you to select a value that is either 1 or 0.

use Extended\ACF\Fields\TrueFalse;

TrueFalse::make('Social Media', 'display_social_media')
    ->helperText('Select whether to display social media links or not.')
    ->stylized(on: 'Yes', off: 'No') // optional on and off text labels


Link - The link field provides a simple way to select or define a link (url, title, target).

use Extended\ACF\Fields\Link;

Link::make('Read More Link')
    ->format('array') // url, array (default)

Page Link - The page link field allows the selection of 1 or more posts, pages or custom post types.

use Extended\ACF\Fields\PageLink;

PageLink::make('Contact Link')
    ->postStatus(['publish']) // draft, future, pending, private, publish

Post Object - The post object field creates a select field where the choices are your pages + posts + custom post types.

use Extended\ACF\Fields\PostObject;

    ->helperText('Select an animal')
    ->postStatus(['publish']) // draft, future, pending, private, publish
    ->format('object') // id, object (default)

Relationship - The relationship field creates a very attractive version of the post object field.

use Extended\ACF\Fields\Relationship;

    ->helperText('Add the contacts.')
    ->postStatus(['publish']) // draft, future, pending, private, publish
    ->format('object') // id, object (default)

Taxonomy - The taxonomy field allows the selection of 1 or more taxonomy terms.

use Extended\ACF\Fields\Taxonomy;

    ->helperText('Select one or more cinema terms.')
    ->appearance('checkbox') // checkbox, multi_select, radio, select
    ->format('id') // object, id (default)
    ->create(false) // false or true (default)
    ->load(true) // true or false (default)
    ->save(true) // true or false (default)x
    ->format('id'), // object or id (default)

User - The user field creates a select field for all your users.

use Extended\ACF\Fields\User;

    ->roles(['administrator', 'editor']) // administrator, author, contributor, editor, subscriber
    ->format('array'), // id, object, array (default)


Color Picker - The color picker field allows a color to be selected via a JavaScript popup.

use Extended\ACF\Fields\ColorPicker;

ColorPicker::make('Text Color')
    ->helperText('Add the text color.')
    ->format('string') // array, string (default)

Date Picker - The date picker field creates a jQuery date selection popup.

use Extended\ACF\Fields\DatePicker;

    ->helperText('Add the employee\'s birthday.')

Icon Picker - The icon picker field allows you to easily select a Dashicon, a Media Library image, or a URL for an image or SVG.

use Extended\ACF\Fields\IconPicker;

    ->helperText('Add the icon.')
    ->format('string') // array, string (default)
    ->tabs(['dashicons']) // [dashicons, media_library, url] (default)

Time Picker - The time picker field creates a jQuery time selection popup.

use Extended\ACF\Fields\TimePicker;

TimePicker::make('Start Time', 'time')
    ->helperText('Add the start time.')

Date Time Picker - The date time picker field creates a jQuery date & time selection popup.

use Extended\ACF\Fields\DateTimePicker;

DateTimePicker::make('Event Date', 'date')
    ->helperText('Add the event\'s start date and time.')
    ->displayFormat('d-m-Y H:i')
    ->format('d-m-Y H:i')
    ->firstDayOfWeek(1) // Sunday is 0, Monday is 1, or use `weekStartsOnMonday` or `weekStartsOnSunday`

Google Map - The Google Map field creates an interactive map with the ability to place a marker.

use Extended\ACF\Fields\GoogleMap;

GoogleMap::make('Address', 'address')
    ->helperText('Add the Google Map address.')
    ->center(57.456286, 18.377716)


Accordion - The accordion field is used to organize fields into collapsible panels.

use Extended\ACF\Fields\Accordion;


// Allow accordion to remain open when other accordions are opened.
// Any field after this accordion will become a child.


// This field will not be visible, but will end the accordion above.
// Any fields added after this will not be a child to the accordion.

Clone - The clone field enables you to choose and showcase pre-existing fields or groups. This field does not possess a custom field class. Instead, you can create a new file for your field and import it using the require statement whenever necessary.

// fields/email.php
use Extended\ACF\Fields\Email;

return Email::make('Email')->required();

// employee.php
    'fields' => [
        require __DIR__.'/fields/email.php';

Flexible Content - The flexible content field acts as a blank canvas to which you can add an unlimited number of layouts with full control over the order.

use Extended\ACF\Fields\FlexibleContent;
use Extended\ACF\Fields\Layout;
use Extended\ACF\Fields\Text;

    ->helperText('Add the page blocks.')
    ->button('Add Component')

Group - The group allows you to create a group of sub fields.

use Extended\ACF\Fields\Group;
use Extended\ACF\Fields\Image;
use Extended\ACF\Fields\Text;

    ->helperText('Add a hero block with title, content and image to the page.')
        Image::make('Background Image'),

Message - The message fields allows you to display a text message.

use Extended\ACF\Fields\Message;

    ->body('George. One point twenty-one gigawatts.')

Repeater - The repeater field allows you to create a set of sub fields which can be repeated again and again whilst editing content!

use Extended\ACF\Fields\Image;
use Extended\ACF\Fields\Repeater;
use Extended\ACF\Fields\Text;

    ->helperText('Add the employees.')
        Image::make('Profile Picture'),
    ->button('Add employee')
    ->layout('table') // block, row, table

Tab - The tab field groups fields into tabbed sections. Fields or groups added after a tab become its children. Enabling endpoint on a tab creates a new group of tabs.

use Extended\ACF\Fields\Tab;

Tab::make('Tab 1'),
Tab::make('Tab 2'),
Tab::make('Tab 3')
    ->placement('top') // top, left
    ->selected() // specify which tab should be selected by default
    ->endpoint(), // This will make a break in the tabs and create a new group of tabs


The Location class allows you to write custom location rules without specifying the name, operator, and value keys. If no operator is provided, it will use the operator as the value. For additional details on custom location rules, please visit this link.

use Extended\ACF\Location;

Location::where('post_type', 'post')->and('post_type', '!=', 'post') // available operators: ==, !=


The if method was renamed to where in version 12, see the upgrade guide.

Conditional Logic

The conditional class helps you write conditional logic without knowing the field keys.

use Extended\ACF\ConditionalLogic;
use Extended\ACF\Fields\File;
use Extended\ACF\Fields\Select;
use Extended\ACF\Fields\URL;
use Extended\ACF\Fields\Textarea;
use Extended\ACF\Fields\Text;

        'document' => 'Document',
        'link' => 'Link to resource',
        'embed' => 'Embed',
File::make('Document', 'file')
        ConditionalLogic::where('type', '==', 'document') // available operators: ==, !=, >, <, ==pattern, ==contains, ==empty, !=empty
URL::make('Link', 'url')
        ConditionalLogic::where('type', '==', 'link')

// "and" condition
Textarea::make('Embed Code')
        ConditionalLogic::where('type', '!=', 'document')->and('type', '!=', 'link')

// use multiple conditional logic for "or" condition
        ConditionalLogic::where('type', '!=', 'document'),
        ConditionalLogic::where('type', '!=', 'link')

// conditional logic that relies on another field from a different field group
Text::make('Sub Title')
        group: 'other-group',
        name: 'enable_highlight', 
        operator: '==', 
        value: 'on', 



The helperText method supports Markdown for the elements listed below.

    ->helperText('__strong__ **strong** _italic_ *italic* `code` [link](')


The column property is not a standard in ACF. It is used as a shorthand for setting the width of the field wrapper. You can provide a number between 0 and 100 as its value.

    ->column(50) // shorthand for ->wrapper(['width' => 50])

dd and dump

The dd and dump methods are non-standard and not available in ACF. These methods are used for debugging.


To use the dd and dump methods, you need to install symfony/var-dumper.

composer require symfony/var-dumper --dev


The key method enables you to define a custom field key. The key should consist of alphanumeric characters and underscores, and must be prefixed with either field_ or layout_.


You can use the key argument to provide a custom field key in conditional logic.

  name: 'color', 
  operator: '==', 
  value: 'red'
  key: 'field_123abc', 


Avoid using custom field keys unless you thoroughly understand them. The field keys are automatically generated when you use the register_extended_field_group function.


The withSettings method overwrites any existing settings on the field when you want to add custom settings.

	->withSettings(['my-new-setting' => 'value'])

Another option for adding custom settings is to extend the field classes provided in the package. Please refer to the custom fields section.

namespace App\Fields;

use Extended\ACF\Fields\Select as Field;

class Select extends Field
    public function myNewSetting(string $value): static
        $this->settings['my-new-setting'] = $value;

        return $this;

Custom Fields

To create custom field classes, you can extend the base field class. Additionally, you can import available setting traits to add common methods like required and helperText.

namespace App\Fields;

use Extended\ACF\Fields\Field;
use Extended\ACF\Fields\Settings\HelperText;
use Extended\ACF\Fields\Settings\Required;

class OpenStreetMap extends Field
    use HelperText;
    use Required;

    protected $type = 'open_street_map';

    public function latitude(float $latitude): static
        $this->settings['latitude'] = $latitude;

        return $this;
    public function longitude(float $longitude): static
        $this->settings['longitude'] = $longitude;

        return $this;
    public function zoom(float $zoom): static
        $this->settings['zoom'] = $zoom;

        return $this;

When you're ready, you can import and use your field just like any other field in this library.

use App\Fields\OpenStreetMap;


Upgrade Guide

The upgrade guide provides information about the breaking changes in the package, now named vinkla/extended-acf. If you have version 12 or lower, you can update by replacing the package name in your composer.json file. This ensures that everything works as expected and you receive updates.

-"wordplate/acf": "^12.0",
+"vinkla/extended-acf": "^12.0"


The Url class has been renamed to URL.

-use Extended\ACF\Fields\Url;
+use Extended\ACF\Fields\URL;

-Url::make('GitHub URL')
+URL::make('GitHub URL')

The WysiwygEditor class has been renamed to WYSIWYGEditor.

-use Extended\ACF\Fields\WysiwygEditor;
+use Extended\ACF\Fields\WYSIWYGEditor;


The defaultValue method has been renamed to default.

-Text::make('Name')->defaultValue('Jeffrey Way')
+Text::make('Name')->default('Jeffrey Way')

The instructions method has been renamed to helperText.

-Text::make('Title')->instructions('Add the title text.')
+Text::make('Title')->helperText('Add the title text.')

The allowMultiple method has been renamed to multiple.


The allowNull method has been renamed to nullable.


The characterLimit method has been renamed to maxLength.


The pagination method has been renamed to paginated.


The buttonLabel method has been renamed to button.

-Repeater::make('Cats')->buttonLabel('Add Cat')
+Repeater::make('Cata')->button('Add Cat')

The weekStartsOn method has been renamed to firstDayOfWeek.

+DatePicker::make('Date')->firstDayOfWeek(1) // or use `weekStartsOnMonday` or `weekStartsOnSunday`

The prepend method has been renamed to prefix.


The append method has been renamed to suffix.


The stylisedUi method has been renamed to stylized on the TrueFalse field.

-TrueFalse::make('Disabled')->stylisedUi(onText: 'Yes')
+TrueFalse::make('Disabled')->stylized(on: 'Yes')

The stylisedUi method has been split into two methods stylized and lazyLoad on the Select field.



The fileSize method has been split into two methods minSize and maxSize.

-Image::make('Background')->fileSize('400 KB', 5)
+Image::make('Background')->minSize('400 KB')->maxSize(5)

The height method has been split into two methods minHeight and maxHeight.

-Gallery::make('Carousel')->height(100, 1000)

The width method has been split into two methods minWidth and maxWidth.

-Image::make('Product Image')->width(100, 1000)
+Image::make('Product Image')->minWidth(100)->maxWidth(1000)

The insert method has been renamed to prependFiles.


The min and max methods has been renamed to minFiles and maxFiles on the Gallery field.


The min and max methods has been renamed to minPosts and maxPosts on the Relationship field.


The min and max methods has been renamed to minRows and maxRows on the Repeater field.


The min and max methods has been renamed to minLayouts and maxLayouts on the FlexibleContent field.


The min and max methods has been renamed to minInstances and maxInstances on the Layout field.


The mimeTypes method has been renamed to acceptedFileTypes.


The enableOpacity method has been renamed to opacity.


The delay method has been renamed to lazyLoad.


The mediaUpload method has been renamed to disableMediaUpload.


The message method has been renamed to body.


The allowArchives method has been renamed to disableArchives.


The addTerm, loadTerms and saveTerms methods has been renamed to create, load and save.


The returnFormat method has been renamed to format on all fields.


The Instructions trait has been renamed to HelperText.

-use Extended\ACF\Fields\Settings\Instructions;
+use Extended\ACF\Fields\Settings\HelperText;

The MimeTypes trait has been renamed to FileTypes.

-use Extended\ACF\Fields\Settings\MimeTypes;
+use Extended\ACF\Fields\Settings\FileTypes;

The CharacterLimit trait has been renamed to MaxLength.

-use Extended\ACF\Fields\Settings\CharacterLimit;
+use Extended\ACF\Fields\Settings\MaxLength;

The Pending trait has been renamed to Affixable.

-use Extended\ACF\Fields\Settings\Pending;
+use Extended\ACF\Fields\Settings\Affixable;

The Writable trait has been renamed to Immutable.

-use Extended\ACF\Fields\Settings\Writable;
+use Extended\ACF\Fields\Settings\Immutable;

The SubFields trait has been renamed to Fields.

-use Extended\ACF\Fields\Settings\SubFields;
+use Extended\ACF\Fields\Settings\Fields;

The Message and ReturnFormat traits has been removed.

-use Extended\ACF\Fields\Settings\Message;
-use Extended\ACF\Fields\Settings\ReturnFormat;

Changelog: 13.0.0...14.0.0


If you're upgrading to version 13, you'll also need to update your imports. The namespace has been changed to Extended\ACF.

-use WordPlate\Acf\Fields\Text;
-use WordPlate\Acf\Fields\Number;
+use Extended\ACF\Fields\Text;
+use Extended\ACF\Fields\Number;

Changelog: 12.0.0...13.0.0


The location query method if has been replaced with where. Please update your field groups accordingly.

use Extended\ACF\Location;

-Location::if('post_type', 'post')
+Location::where('post_type', 'post')

Changelog: 11.0.0...12.0.0


The field name is now automatically formatted as snake_case instead of kebab-case.

-Text::make('Organization Number') // organization-number
+Text::make('Organization Number') // organization_number

The Radio field has been renamed to RadioButton.


The Wysiwyg field has been renamed to WysiwygEditor.


Changelog: 10.0.0...11.0.0