Skip to content

Commit

Permalink
⚡️ Transform blocks to block.json when caching (#224)
Browse files Browse the repository at this point in the history
  • Loading branch information
Log1x authored Mar 1, 2024
1 parent af6cd95 commit e66d462
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 83 deletions.
37 changes: 37 additions & 0 deletions src/AcfComposer.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public function boot(): void
return;
}

$this->handleBlocks();
$this->registerDefaultPath();

foreach ($this->composers as $namespace => $composers) {
Expand All @@ -110,6 +111,26 @@ public function boot(): void
$this->booted = true;
}

/**
* Handle the block rendering.
*/
protected function handleBlocks(): void
{
add_filter('acf_block_render_template', function ($block, $content, $is_preview, $post_id, $wp_block, $context) {
if (! class_exists($composer = $block['render_template'] ?? '')) {
return;
}

if (! $composer = app('AcfComposer')->getComposer($composer)) {
return;
}

method_exists($composer, 'assets') && $composer->assets($block);

echo $composer->render($block, $content, $is_preview, $post_id, $wp_block, $context);
}, 10, 6);
}

/**
* Register the default application path.
*/
Expand Down Expand Up @@ -208,6 +229,22 @@ public function composers(): array
return $this->composers;
}

/**
* Retrieve a Composer instance by class name.
*/
public function getComposer(string $class): ?Composer
{
foreach ($this->composers as $composers) {
foreach ($composers as $composer) {
if ($composer::class === $class) {
return $composer;
}
}
}

return null;
}

/**
* Retrieve the registered paths.
*/
Expand Down
158 changes: 108 additions & 50 deletions src/Block.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ abstract class Block extends Composer implements BlockContract
*/
public $view;

/**
* The block settings.
*/
public ?Collection $settings = null;

/**
* The block description.
*
Expand Down Expand Up @@ -271,7 +276,7 @@ public function getStyle(): ?string
return Str::of($this->block->className ?? null)
->matchAll('/is-style-(\S+)/')
->get(0) ??
Arr::get(collect($this->block->styles)->firstWhere('isDefault'), 'name');
Arr::get(collect($this->getStyles())->firstWhere('isDefault'), 'name');
}

/**
Expand Down Expand Up @@ -375,61 +380,114 @@ public function compose(): ?self
]);
}

$this->register(function () {
$settings = [
'name' => $this->slug,
'title' => $this->name,
'description' => $this->description,
'category' => $this->category,
'icon' => $this->icon,
'keywords' => $this->keywords,
'parent' => $this->parent ?: null,
'ancestor' => $this->ancestor ?: null,
'post_types' => $this->post_types,
'mode' => $this->mode,
'align' => $this->align,
'align_text' => $this->align_text ?? $this->align,
'align_content' => $this->align_content,
'styles' => $this->getStyles(),
'supports' => $this->supports,
'enqueue_assets' => fn ($block) => method_exists($this, 'assets') ? $this->assets($block) : null,
'render_callback' => function (
$block,
$content = '',
$preview = false,
$post_id = 0,
$wp_block = false,
$context = false
) {
echo $this->render($block, $content, $preview, $post_id, $wp_block, $context);
},
];
$this->register(fn () => $this->hasJson()
? register_block_type($this->jsonPath())
: acf_register_block_type($this->settings()->all())
);

if ($this->example !== false) {
if (method_exists($this, 'example') && is_array($example = $this->example())) {
$this->example = array_merge($this->example, $example);
}

$settings = Arr::add($settings, 'example', [
'attributes' => [
'mode' => 'preview',
'data' => $this->example,
],
]);
}
return $this;
}

if (! empty($this->uses_context)) {
$settings['uses_context'] = $this->uses_context;
}
/**
* Retrieve the block settings.
*/
public function settings(): Collection
{
if ($this->settings) {
return $this->settings;
}

if (! empty($this->provides_context)) {
$settings['provides_context'] = $this->provides_context;
if ($this->supports) {
$this->supports = collect($this->supports)
->mapWithKeys(fn ($value, $key) => [Str::camel($key) => $value])
->merge($this->supports)
->all();
}

$settings = Collection::make([
'name' => $this->slug,
'title' => $this->name,
'description' => $this->description,
'category' => $this->category,
'icon' => $this->icon,
'keywords' => $this->keywords,
'parent' => $this->parent ?: null,
'ancestor' => $this->ancestor ?: null,
'post_types' => $this->post_types,
'mode' => $this->mode,
'align' => $this->align,
'align_text' => $this->align_text ?? $this->align,
'align_content' => $this->align_content,
'styles' => $this->getStyles(),
'supports' => $this->supports,
'enqueue_assets' => fn ($block) => method_exists($this, 'assets') ? $this->assets($block) : null,
'render_callback' => function (
$block,
$content = '',
$preview = false,
$post_id = 0,
$wp_block = false,
$context = false
) {
echo $this->render($block, $content, $preview, $post_id, $wp_block, $context);
},
]);

if ($this->example !== false) {
if (method_exists($this, 'example') && is_array($example = $this->example())) {
$this->example = array_merge($this->example, $example);
}

acf_register_block_type($settings);
});
$settings = $settings->put('example', [
'attributes' => [
'mode' => 'preview',
'data' => $this->example,
],
]);
}

return $this;
if (! empty($this->uses_context)) {
$settings = $settings->put('uses_context', $this->uses_context);
}

if (! empty($this->provides_context)) {
$settings = $settings->put('provides_context', $this->provides_context);
}

return $this->settings = $settings;
}

/**
* Retrieve the Block settings as JSON.
*/
public function toJson(): string
{
$settings = $this->settings()->forget([
'enqueue_assets',
'render_callback',
'mode',
])->put('acf', [
'mode' => $this->mode,
'renderTemplate' => $this::class,
]);

return $settings->filter()->toJson(JSON_PRETTY_PRINT);
}

/**
* Retrieve the Block JSON path.
*/
public function jsonPath(): string
{
return $this->composer->manifest()->path("blocks/{$this->slug}/block.json");
}

/**
* Determine if the block has a JSON file.
*/
public function hasJson(): bool
{
return file_exists($this->jsonPath());
}

/**
Expand Down
15 changes: 10 additions & 5 deletions src/Console/CacheCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ class CacheCommand extends Command
* @var string
*/
protected $signature = 'acf:cache
{--clear : Clear the cached field groups}
{--clear : Clear the cache}
{--status : Show the current cache status}
{--force : Force cache the field groups}';
{--manifest : Only write the field group manifest}
{--force : Ignore errors when writing cache}';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Cache the ACF field groups';
protected $description = 'Cache the ACF Composer field groups and blocks.';

/**
* The ACF Composer instance.
Expand Down Expand Up @@ -69,10 +70,14 @@ public function handle()
return $this->components->error('Failed to cache the <fg=red>ACF Composer</> field groups.');
}

if (! $this->composer->manifest()->write()) {
if (! $manifest = $this->composer->manifest()->write()) {
return $this->components->error('Failed to write the <fg=red>ACF Composer</> manifest.');
}

$this->components->info("<fg=blue>{$this->count}</> field group(s) cached successfully.");
$blocks = ! $this->option('manifest')
? $this->composer->manifest()->writeBlocks()
: 0;

$this->components->info("Successfully cached <fg=blue>{$manifest}</> field(s) and <fg=blue>{$blocks}</> block(s).");
}
}
6 changes: 3 additions & 3 deletions src/Console/ClearCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ClearCommand extends Command
*
* @var string
*/
protected $description = 'Clear the ACF field group cache';
protected $description = 'Clear the ACF Composer cache.';

/**
* The ACF Composer instance.
Expand All @@ -34,7 +34,7 @@ public function handle()
$this->composer = $this->laravel['AcfComposer'];

return $this->composer->manifest()->delete()
? $this->components->info('Successfully cleared the <fg=blue>ACF Composer</> cache manifest.')
: $this->components->info('The <fg=blue>ACF Composer</> cache manifest is already cleared.');
? $this->components->info('Successfully cleared the <fg=blue>ACF Composer</> cache.')
: $this->components->info('The <fg=blue>ACF Composer</> cache is already cleared.');
}
}
Loading

0 comments on commit e66d462

Please sign in to comment.