ACFComposer - how to use sub_fields?

I am just learning how to use ACFComposer and can’t figure out how to add some sub_field to a FlexibleContent field. I want to eventually use field partials but would like to start with adding fields directly in addLayout. I’m not finding any example code from ACFComposer, ACFBuilder or from Log1x’s awesome cheatsheet. that actually shows what goes in 'sub_fields' => [] I’m a bit lost.

Any sample code or direction would be appreciated, thank you,

<?php

namespace App\Fields;

use Log1x\AcfComposer\Field;
use StoutLogic\AcfBuilder\FieldsBuilder;
use App\Fields\Partials\ListItems;

class Examples extends Field
{
    /**
     * The field group.
     *
     * @return array
     */
    public function fields()
    {
        $example = new FieldsBuilder('example');

        $example
            ->setLocation('page_template', '==', 'template-development-flexible-content.blade.php');

        $example
	        ->addFlexibleContent('flexible_content_field', [
		        'instructions' => '',
		        'required' => 0,
		        'conditional_logic' => [],
		        'wrapper' => [
			        'width' => '',
			        'class' => '',
			        'id' => '',
		        ],
		        'button_label' => 'Add Row',
		        'min' => '',
		        'max' => '',
	        ])


	        ->addLayout('layout', [
		        'label' => 'Layout',
		        'display' => 'block',
		        'sub_fields' => [],
		        'min' => '',
		        'max' => '',
	        ]);
		
        return $example->build();
    }
}

I figured it out. :grinning:

Fields need to be defined separately and then simply listed: 'sub_fields' => ['list_items'],

EZPZ

Could you show me a full code example?

// this is where you define the fields of this layout
use App\Fields\Layout;

class Modules extends Partial {

	public function fields() {
		$modules = new FieldsBuilder('Modules');

		$modules->addFlexibleContent('modules')
			->addLayout($this->get(Layout::class))
		->endFlexibleContent();

		return $modules;
	}
}

I’m a little bit confused. I want to use the partials as the subfields. But I’m not able to get this work, also with your example.

This is my partial

<?php

namespace App\Fields\Partials;

use Log1x\AcfComposer\Partial;
use StoutLogic\AcfBuilder\FieldsBuilder;

class PageHeader extends Partial
{
    /**
     * The partial field group.
     *
     * @return \StoutLogic\AcfBuilder\FieldsBuilder
     */
    public function fields()
    {
        $pageHeader = new FieldsBuilder('page_header');

        $pageHeader
            ->addText('title');

        return $pageHeader;
    }
}

And this is my Flexible content file

<?php

namespace App\Fields;

use Log1x\AcfComposer\Field;
use StoutLogic\AcfBuilder\FieldsBuilder;
use App\Fields\Partials\PageHeader;

class PageBuilder extends Field
{
    /**
     * The field group.
     *
     * @return array
     */
    public function fields()
    {
        $pageBuilder = new FieldsBuilder('page_builder');

        $pageBuilder
            ->setLocation('post_type', '==', 'page');

        $pageBuilder
            ->addFlexibleContent('page_builder', [
                'instructions' => '',
                'required' => 0,
                'conditional_logic' => [],
                'wrapper' => [
                'width' => '',
                'class' => '',
                'id' => '',
                ],
                'button_label' => 'Content item toevoegen',
                'min' => '',
                'max' => '',
            ])

            ->addLayout('Header', [
                'label' => 'Header',
                'display' => 'block',
                'sub_fields' => [
                    [
                        $this->get(PageHeader::class)
                    ],
                ],
                'min' => '',
                'max' => '',
            ]);

        return $pageBuilder->build();
    }
}

I’m not able to get the sub_fields working

Did you ever get this to work? I cannot either.

Without using a partial you do:

  ->addFlexibleContent('flexible_content_field', [
                    'instructions'      => '',
                    'required'          => 0,
                    'conditional_logic' => [],
                    'wrapper'           => [
                        'width' => '',
                        'class' => '',
                        'id'    => '',
                    ],
                    'button_label'      => 'Add Row',
                    'min'               => '',
                    'max'               => '',
                ])
                ->addLayout('layout', [
                    'label'      => 'Layout',
                    'display'    => 'block',
                    'sub_fields' => ['text_example'],
                    'min'        => '',
                    'max'        => '',
                ])
                ->addText('text_example', [
                    'label'             => 'Text',
                    'instructions'      => '',
                    'required'          => 0,
                    'conditional_logic' => [],
                    'wrapper'           => [
                        'width' => '',
                        'class' => '',
                        'id'    => '',
                    ],
                    'default_value'     => '',
                    'placeholder'       => '',
                    'prepend'           => '',
                    'append'            => '',
                    'maxlength'         => '',
                ])
                ->endFlexibleContent();

The text will be an item in the flexible content layout. You can add whatever fields you like in between layout and endFlexibleContent()

Using a partial I got it to work by:

public function fields() {

            // Parent Field
            $imageWithContent = new FieldsBuilder('image_with_content');

            // Sub Field
            $title = $this->get(Title::class);
            $content = $this->get(Content::class);
            $accordion = $this->get(AccordionItem::class);
            $button = $this->get(Button::class);

            // Build Layout
            $imageWithContent
                ->addButtonGroup('style_settings', [
                    'label'         => 'Decor',
                    'choices'       => [
                        'plain' => 'Plain',
                        'line'  => 'Line',
                    ],
                    'default_value' => 'plain',
                    'position'      => 'side',
                ])
                ->addImage('image', [
                    'label'   => 'Image',
                    'wrapper' => ['width' => '50%'],
                ])
                ->addFlexibleContent('flexible_content_field', [
                    'button_label' => 'Add Content',
                    'wrapper'      => ['width' => '50%'],
                ])
                ->addLayout($title, [
                    'label'   => 'Title',
                    'display' => 'block',
                ])
                ->addLayout($content, [
                    'label'   => 'Content',
                    'display' => 'block',
                ])
                ->addLayout($accordion, [
                    'label'   => 'Accordion',
                    'display' => 'block',
                ])
                ->addLayout($button, [
                    'label'   => 'Button',
                    'display' => 'block',
                ])
                ->endFlexibleContent();

            return $imageWithContent->build();
        }

If you have a Flexible content field you can add partials by just doing this:

        $flexibleBuilder = $builder->addFlexibleContent('flexible_content_field', [
            'button_label' => 'Module toevoegen',
        ]);

        $flexibleBuilder
            ->addLayout($this->get(Header::class))
        ;

        return $builder->build();

This is the example Partial:

class Header extends Partial
{
    public function fields()
    {
        $fields = new FieldsBuilder('header', [
            'label' => 'Header',
            'layout' => 'block',
        ]);

        $fields
            ->addFields($this->get(ModulesDefaults::class)) // Default flexible content fields
            ->addTrueFalse('align_content', [
                'label' => 'Tekst rechts uitlijnen',
                'ui' => 1,
            ])
            ->addText('title' , [
                'label' => 'Titel',
            ])
        ;

        return $fields;
    }
}

Tip: If you are building a page builder and have multiple layouts in a folder you can use the following to add all the layouts:

        $flexibleBuilder = $builder->addFlexibleContent('flexible_content_field', [
            'button_label' => 'Module toevoegen',
        ]);

        collect(glob(__DIR__.'/Modules/*.php'))->map(function ($file) use ($flexibleBuilder) {
            $module = str_replace('.php', '', basename($file));
            $class = 'App\Fields\Modules\\' . $module;
            $flexibleBuilder->addLayout($this->get($class));
        });

        return $builder->build();