How to give unique keys for repeated acf-composer partials in the same block

Hi,

I’m using acf-composer and working on partials for my blocks. One of these partials is to reuse a Headline partial multiple times in a block, but each instance needs a unique key/name as otherwise it gives me error ofcourse.

From my findings the usual fields() method doesn’t get any arguments, because it’s called during the parent constructor. So the key I pass via addPartial(Headline::class, ['name' => 'headline_1']) isn’t available there.

Currently, the only way I’ve got it working is by building all fields inside compose($args) instead of fields(). This seems to work but feels like a hacky way of doing it and my cause problems in the future?

<?php

namespace App\Fields\Partials;

use Log1x\AcfComposer\Builder;
use Log1x\AcfComposer\Partial;

class Headline extends Partial
{
    public function compose(array $args = []): Builder
    {
        
        $key = $args['name'];
        
        return Builder::make($key)
            ->addGroup($key, ['label' => 'Headline'])
            ->addText('text', ['label' => 'Text'])
            ->addSelect('type', [
                'label' => 'Type',
                'choices' => ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
                'ui' => 1,
                'allow_null' => 1,
                'return_format' => 'value',
                'placeholder' => 'Select headline type',
            ])
            ->endGroup();
    }
}

My question: is there a simpler or built-in way to assign a custom key/name to partial instances without having to do this?

Thanks!

1 Like

@Log1x what are your thoughts on this solution? Is there a better way of doing this?

I don’t have an example on hand but in the past I’ve used Modifying Fields · StoutLogic/acf-builder Wiki · GitHub

Thanks for the reply @Log1x. Tried modifying fields, but it throws a FieldNotFoundException when I try to change the name, which makes sense, I guess.

One solution that requires no “custom” configuration is just to wrap it in a group like this:

$fields
    ->addGroup('headline_1', ['label' => ''])
        ->addPartial(Headline::class)
    ->endGroup();

Though it feels a little messy and some partials I don’t want to group, which requires additional code writing. So I sat down yesterday and came up with this more “refined” solution. Still not sure if I’ll have any hiccups with this in the future, but it seems to work:

<?php
namespace App\Fields\Partials;

use Log1x\AcfComposer\Builder;
use Log1x\AcfComposer\Partial;

class Headline extends Partial
{
    public ?string $prefix = null;
    public string $name = 'headline';

    public function compose(array $args = [])
    {
        // Apply prefix and fallback name
        $this->prefix = $args['prefix'] ?? '';
        if ($this->prefix) {
            $this->name = 'headline_' . $this->prefix;
        }

        return parent::compose($args);
    }

    public function fields(): Builder
    {
        $fields = Builder::make($this->name);
        $fields
            ->addGroup($this->name, ['label' => 'Headline'])
                ->addText('text', ['label' => 'Text'])
                ->addSelect('type', [
                    'label' => 'Type',
                    'choices' => ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
                    'ui' => 1,
                    'allow_null' => 1,
                    'return_format' => 'value',
                ])
            ->endGroup();

        return $fields;
    }
}

And this is how I call it on the block part:

$fields
    ->addPartial(Headline::class, ['prefix' => 'primary']);

With modifying fields, you can also do the following for having unique labels for the same partial:

$fields
    ->addPartial(Headline::class, ['prefix' => 'primary'])
    ->modifyField('headline_primary', ['label' => 'Headline (primary)']);

The fields method also receive $args by the way.

1 Like