Log1x / acf-composer

Compose ACF Fields, Blocks, Widgets, and Option Pages with ACF Builder on Sage 10.
https://github.com/Log1x/acf-composer
MIT License
398 stars 53 forks source link

Support for block.json ? #223

Closed mLicorn closed 4 months ago

mLicorn commented 4 months ago

Hello,

I saw on this topic that you were thinking about integrating the block.json file into ACF Composer.

This functionality is going to become vital in view of WordPress 6.5’s developments with the Interactivity API. ACF has added support for block.json in version 6 and encourages us to migrate our blocks to this system to take advantage of all WordPress evolutions.

Have you had time to think about adding this feature?

Log1x commented 4 months ago

I haven't looked into it yet but it's high on the list to see if I can implement it cleanly. Ideally the block.json will get generated with the cache command or something.

I still have yet to see a feature/enhancement that is not usable when registering the blocks with PHP though. In the end, the block.json is/will still being registered with PHP using register_block_type and I imagine the block.json gets turned into a WP_Block_Type - so whether we actually need to generate block.json files or just imitate the behavior with registration is yet to be determined.

Log1x commented 4 months ago

Yeah, I'm not seeing a need to actually generate block.json files at any point. We can just create the block the same way block.json gets handled with register_block_type_from_metadata.

One of the main things to do is bump the API version.

mLicorn commented 4 months ago

That's what I'm looking at and testing on 6.5 beta-3, and I think you're right: the block.json file is just an easy way to configure a block, but everything can be done in PHP.

Log1x commented 4 months ago

224

There was in-fact a perk – blocks are much faster in the backend. ⚡

mLicorn commented 4 months ago

Thanks for the feature: I've just tested it and it works perfectly.

For those who'd like to test the Interactivity API with ACF Composer, here's the test I've set up. (My apologies if this isn't the right place to share this)

app/Blocks/TestInteractivityAPI.php

<?php

namespace App\Blocks;

use Log1x\AcfComposer\Block;
use Log1x\AcfComposer\Builder;

class TestInteractivityAPI extends Block
{
    public $slug = 'test-interactivity-api';

    public $view = 'blocks.test.interactivity-api';

    /**
     * The block attributes.
     */
    public function attributes(): array
    {
        return [
            'name'          => __('Test interactivity API', 'sage'),
            'description'   => __('A simple Test block.', 'sage'),
            'category'      => 'formatting',
            'icon'          => 'rest-api',
            'keywords'      => [],
            'post_types'    => [],
            'parent'        => [],
            'ancestor'      => [],
            'mode'          => 'preview',
            'align'         => '',
            'align_text'    => '',
            'align_content' => '',
            'supports'      => [
                'interactivity' => true,
                'align'         => true,
                'align_text'    => false,
                'align_content' => false,
                'full_height'   => false,
                'anchor'        => false,
                'mode'          => false,
                'multiple'      => true,
                'jsx'           => true,
                'color'         => [
                    'background' => true,
                    'text'       => true,
                    'gradient'   => true,
                ],
            ],
            'styles'   => ['light', 'dark'],
            'template' => [
                'core/heading'   => ['placeholder' => 'Hello World'],
                'core/paragraph' => ['placeholder' => 'Welcome to the Test block.'],
            ],
        ];
    }

    /**
     * The example data.
     */
    public function example(): array
    {
        return [
            'items' => [
                ['item' => 'Item one'],
                ['item' => 'Item two'],
                ['item' => 'Item three'],
            ],
        ];
    }

    /**
     * Data to be passed to the block before rendering.
     */
    public function with(): array
    {
        return [
            'items' => $this->items(),
        ];
    }

    /**
     * The block field group.
     */
    public function fields(): array
    {
        $test = Builder::make($this->slug);

        $test
            ->addRepeater('items')
            ->addText('item')
            ->endRepeater();

        return $test->build();
    }

    /**
     * Return the items field.
     *
     * @return array
     */
    public function items()
    {
        return get_field('items') ?: $this->example()['items'];
    }

    /**
     * Assets enqueued when rendering the block.
     */
    public function assets(array $block): void
    {
        if ($this->supports['interactivity'] ?? false) {
            add_action('wp_enqueue_scripts', fn () => wp_enqueue_script_module('@wordpress/interactivity'), 100);
        }
    }
}

resources/views/test/preview-interactivity-api.blade.php

<div
  class="{{ $block->classes }}"
  style="{{ $block->inlineStyle }}"
>
  <div>
    <InnerBlocks template="{{ $block->template }}" />
  </div>

  @if ($items)
    <ul>
      @foreach ($items as $item)
        <li>{{ $item['item'] }}</li>
      @endforeach
    </ul>
  @else
    <p>{{ $block->preview ? 'Add an item...' : 'No items found!' }}</p>
  @endif
</div>

resources/views/test/interactivity-api.blade.php

<div
  class="{{ $block->classes }}"
  style="{{ $block->inlineStyle }}"
>
  <div>
    <InnerBlocks template="{{ $block->template }}" />
  </div>

  <ul
    data-wp-interactive
    data-wp-context='{ "list": {{ json_encode($items) }} }'
  >
    <template data-wp-each="context.list">
      <li data-wp-text="context.item.item"></li>
    </template>
  </ul>
</div>
wp acorn acf:cache