Custom Blocks
The Custom_Blocks class (which extends Default_Blocks) lets you register custom Gutenberg blocks powered by ACF. Each block is defined as a config array with its fields and gets a dedicated PHP template for rendering.
Key Features
Section titled βKey Featuresβ- Config-driven: Define blocks as arrays β no manual
acf_register_block_type()calls - Automatic field groups: Fields are registered as local ACF field groups per block
- Template rendering: Each block renders from a PHP template file
- Deterministic keys: Field keys generated with
md5()for consistency - Keyword search: Blocks are searchable in the Gutenberg inserter by keywords
Configuration File
Section titled βConfiguration Fileβfunctions/project/config/custom-blocks_config.php
Each block is an array with these properties:
| Property | Type | Description |
|---|---|---|
block_name | string | Block slug (no spaces, underscores, or special characters) |
template_path | string | Template filename (without .php) in the blocks directory |
singular_name | string | Display name in the Gutenberg inserter |
keywords | string | Comma-separated search keywords |
category | string | Block category (default: 'layout') |
icon | string | Dashicon name (default: 'editor-italic') |
mode | string | 'preview' or 'edit' (default: 'preview') |
fields | array | Array of field configs |
01. Example Configuration
Section titled β01. Example Configurationβ<?phpreturn [ [ 'block_name' => 'customctablock', 'template_path' => 'custom-cta-block', 'singular_name' => 'Custom CTA Block', 'keywords' => 'Custom, CTA, Call to Action', 'fields' => [ [ 'name' => 'pretitle', 'type' => 'text', 'label' => 'CTA Pretitle', ], [ 'name' => 'title', 'type' => 'text', 'label' => 'CTA Title', ], [ 'name' => 'content', 'type' => 'textarea', 'label' => 'CTA Content', ], [ 'name' => 'button', 'type' => 'link', 'label' => 'CTA Button', ], ], ], [ 'block_name' => 'customquote', 'template_path' => 'custom-quote', 'singular_name' => 'Custom Quote', 'keywords' => 'Custom, Quote, Blockquote', 'fields' => [ [ 'name' => 'quote_text', 'type' => 'textarea', 'label' => 'Quote', ], [ 'name' => 'quote_author', 'type' => 'text', 'label' => 'Author', ], ], ],];02. Block Template
Section titled β02. Block TemplateβCreate the template file in functions/project/blocks/:
<?php// $data contains all ACF field values// $block contains block metadata (className, align, etc.)// $is_preview is true when shown in the Gutenberg editor
$pretitle = $data['pretitle'] ?? '';$title = $data['title'] ?? '';$content = $data['content'] ?? '';$button = $data['button'] ?? null;?>
<div class="c--cta-block"> <?php if ($pretitle): ?> <p class="c--cta-block__pretitle"><?php echo esc_html($pretitle); ?></p> <?php endif; ?>
<?php if ($title): ?> <h2 class="c--cta-block__title"><?php echo esc_html($title); ?></h2> <?php endif; ?>
<?php if ($content): ?> <p class="c--cta-block__content"><?php echo esc_html($content); ?></p> <?php endif; ?>
<?php if ($button): ?> <a href="<?php echo esc_url($button['url']); ?>" class="c--cta-block__button" target="<?php echo esc_attr($button['target'] ?: '_self'); ?>"> <?php echo esc_html($button['title']); ?> </a> <?php endif; ?></div>03. Field Types
Section titled β03. Field TypesβBlock fields support all standard ACF field types:
<?php['name' => 'title', 'type' => 'text', 'label' => 'Title'],['name' => 'content', 'type' => 'textarea', 'label' => 'Content'],['name' => 'body', 'type' => 'wysiwyg', 'label' => 'Body'],['name' => 'image', 'type' => 'image', 'label' => 'Image', 'return_format' => 'array'],['name' => 'button', 'type' => 'link', 'label' => 'Button'],['name' => 'gallery', 'type' => 'gallery', 'label' => 'Images', 'return_format' => 'array'],['name' => 'layout', 'type' => 'select', 'label' => 'Layout', 'choices' => ['left' => 'Left', 'right' => 'Right']],Custom Blocks vs Default Blocks
Section titled βCustom Blocks vs Default BlocksβThe framework has two block classes:
| Class | Config Key | Template Directory | Purpose |
|---|---|---|---|
Default_Blocks | default_blocks | functions/framework/blocks/ | Framework-provided blocks (footnote, highlighted) |
Custom_Blocks | custom_blocks | functions/project/blocks/ | Project-specific blocks |
Custom_Blocks extends Default_Blocks and only changes the config key β all registration, field mapping, and rendering logic is shared.
Knowledge Check
Test your understanding of this section
Loading questions...