vinkla / extended-acf

Register advanced custom fields with object-oriented PHP
MIT License
455 stars 61 forks source link

[Feature Request]: Ideas for implementing custom fields #149

Closed vinkla closed 3 months ago

vinkla commented 5 months ago

The application I'm working on contains multiple blocks with the field below. Currently, we have kept the code in a WET approach, copying and pasting the block across all blocks.

Extended\ACF\Fields\Text::make('HTML Anchor ID', 'block_id')->helperText(
    'Enter a word or two — without spaces — to make a unique web address just for this block, called an “anchor.” Then, you’ll be able to link directly to this section of your page. [Learn more about anchors.](https://wordpress.org/documentation/article/page-jumps/)',
);

It would be great to create a custom field class and import it instead:

App\Fields\BlockID::make();

The Field class can be extended. However, if you want to overwrite the make method, you must include the arguments for label and name to comply with the Field class.

App\Fields\BlockID::make('HTML Anchor ID', 'block_id');

What can we do instead? We could set up a new method called create that calls the make method internally, but it would be nice to be able to use the make method without passing any arguments. We can keep all settings internal in the BlockID field class. We could also add default values to the make parmeters.

Do you have any ideas on how to improve this? How do Laravel Nova or Filament handle this?

nikrowell commented 5 months ago

Would it work do use static properties on the custom field and update Field::make to use those if called without arguments? (not sure how static properties work with inheritance)

class BlockID extends Field 
{
    protected static string $label = 'HTML Anchor ID';
    protected static string $name = 'block_id';
}

If not, I think overriding make would be a sufficient given how little that method is doing. Note that I have not yet used extended-acf in production, but I can definitely see the need for creating common / shared fields like this.

vinkla commented 5 months ago

Thanks for sharing ideas @nikrowell 🙌

Would it work do use static properties on the custom field and update Field::make to use those if called without arguments?

This is an interesting idea. Currently, we set the name and label in the $settings property:

https://github.com/vinkla/extended-acf/blob/cd7cd7bf7fa0d75da07096a955ab0c2445e69b9b/src/Fields/Field.php#L25-L31

If not, I think overriding make would be a sufficient given how little that method is doing.

You're probably right. I've solved it by overriding the make method and giving it default values:

final class BlockID extends Text
{
    public static function make(string $label = 'HTML Anchor ID', string|null $name = 'block_id'): static
    {
        return parent::make($label, $name)->helperText(
            'Enter a word or two — without spaces — to make a unique web address just for this block, called an "anchor". Then, you\'ll be able to link directly to this section of your page. [Learn more about anchors.](https://wordpress.org/documentation/article/page-jumps/)',
        );
    }
}