Skip to content
On this page

Field Enums

Advanced Custom Fields

Advanced Custom Fields is a well maintained plugin which enables you to add custom fields to any type of WordPress post. WordPress developers involved in custom built plugins or themes will most likely have come across it, and Forme itself is closely integrated with it.

TIP

ACF is not always the best solution, more complex use cases will often be better served by creating your own admin UI which works directly with your own custom database tables - the trade off is usually around development speed versus somewhat wonky data modelling and database query efficiency.

ACF provides an intuitive UI to configure your fields. This is great for scaffolding stuff out, but our approach is to then always convert this field group set up to php code by enclosing it in one of our FieldGroup classes. This means the configuration is fixed in version control rather than being part of database content, which is inherently brittle.

The Magic Value Problem

One limitation we have found with ACF is that if you then need to reference your fields elsewhere in the codebase, this encourages the use of magic values, an antipattern which quickly becomes unmaintainable as your app grows and the data architecture morphs - you're going to start to want those name strings - which are really just an additional human-readable key anyway but that's an ACF quirk - to be abstracted away and decoupled.

As it stands, you also miss out on having your editor being able to autocomplete your field names, keys and labels.

The Field Enum Pattern

We've come up with a Field Enum pattern as a way to solve this problem. In essence, this replaces the magic strings with typed enum properties which are available at compile time. Apart from reducing unstable copy pasta hell, it also means that your editor can now autocomplete for you, and you get type safety for free - well, not quite free; at the cost of a bit of additional verbosity.

Our abstract AcfEnum class uses Spatie's Enum under the hood - we've added some custom properties for the key, label and name of the field. You need to extend this class and configure it.

php
<?php
declare(strict_types=1);

namespace Foobar\ProjectNameSpace\Enums;

use Forme\Framework\Enums\AcfEnum;

/**
 * @method static self FOO()
 */
final class FooBarField extends AcfEnum
{
    // this maps field key to the field name
    protected $fieldNames = ['field_EJF95fA9n' => 'foo'];

    // this maps enum method name to the field key
    protected static function values(): array
    {
        return ['FOO' => 'field_EJF95fA9n'];
    }

    // this maps enum method name to the field label
    protected static function labels(): array
    {
        return ['FOO' => 'Foo Field'];
    }
}

Then in your ACF field group definition, you can now replace the magic strings with our custom enum properties.

php
<?php
...
    'fields' => [
        [
            'key' => FooBarField::FOO()->key,
            'label' => FooBarField::FOO()->label,
            'name' => FooBarField::FOO()->name,
            'type' => 'text',
            'instructions' => 'Beam me up Scotty',
            'required' => 0,
            'conditional_logic' => 0,
            'wrapper' => [
                'width' => '',
                'class' => '',
                'id' => '',
            ],
            'default_value' => '',
            'placeholder' => '',
            'prepend' => '',
            'append' => '',
            'maxlength' => '',
        ],
    ],
...

You can use this same syntax throughout your codebase to reference your fields.

php
$value = get_field(FooBarField::FOO()->name);

If you want to use them in your views, you'll need to use the fully qualified class name.

php
// plates 4
<?=get_field(/Vendor/MyAwesomePlugin/FooBarField::FOO()->name)?>

Code Generation

The manual replacement process described above can get very laborious and error-prone for larger field groups, so we've added a cli command to automate this.

bash
forme make field-enum FooBar

Follow the instructions to select the Field Group you want to generate an enum for, and choose the enum property names. The cli will generate a new enum class for you, as well as find and replace all the magic strings in the field group definition.

WARNING

This command works fine for fairly straight forward use cases, but struggles with nested field groups and repeaters. YMMV.

Made by Moussa Clarke @ Sanders Web Works with ❤️