Благодаря Elliot Condon, создавшему замечательный плагин Advanced Custom Fields, теперь можно за считанные минуты создавать профессиональные блоки под редактор блоков Gutenberg без знания JavaScript на чистом PHP.
В этом нам поможет новая функция acf_register_block_type(), которая появилась в ACF Pro с версии 5.8.
Параметры функции
acf_register_block_type( $settings );
Где $settings может содержать следующие ключи.
name (строка)
Уникальное имя для блока без неймспейсов. ACF сам добавит префикс, например, testimonial. Может состоять только из символов латинского алфавита в нижнем регистре и тире.
'name' => 'testimonial',
title (строка)
Отображаемый заголовок вашего блока. Например Testimonial.
'title' => __('Testimonial'),
description (строка, опционально)
Короткое описание для вашего блока
'description' => __('My testimonial block.'),
category (строка)
Все блоки группируются в категории для удобного поиска их пользователями. Из коробки существуют следующие категории: common, formatting, layout, widgets и embed.
Плагины и темы также могут регистрировать собственные категории для блоков.
'category' => 'embed',
icon (строка|массив, опционально)
Иконка для блока из набора Dashicons или своя собственная иконка в SVG.
// Specifying a dashicon for the block 'icon' => 'book-alt', // Specifying a custom HTML svg for the block 'icon' => '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0z" /><path d="M19 13H5v-2h14v2z" /></svg>', // Specifying colors 'icon' => array( // Specifying a background color to appear with the icon e.g.: in the inserter. 'background' => '#7e70af', // Specifying a color for the icon (optional: if not set, a readable color will be automatically defined) 'foreground' => '#fff', // Specifying a dashicon for the block 'src' => 'book-alt', ),
keywords (массив, опционально)
Массив включевых слов для вашего блока, по которым пользователь сможет его найти.
'keywords' => array('quote', 'mention', 'cite'),
post_types (массив, опционально)
Массив зарегистрированных типов записей, для которых будет доступен блок.
'post_types' => array('post', 'page'),
mode (строка, опционально)
Вид (режим) отображения вашего блока. Возможные значения: auto, preview и edit. По умолчанию значение равно preview.
Если указать auto, то будет отображаться превью блока, а при выборе блока превью заменится на форму редактирования.
Если указать preview, то превью блока будет отображаться всегда, а форма редактирования станет доступна в боковой колонке.
Если указать edit, то то всегда будет отображаться форма редактирования.
'mode' => 'auto',
align (строка, опционально)
Выравнивание блока по умолчанию. Доступны следующие варианты: left, center, right, wide и full. По умолчанию пустая строка.
'align' => 'full',
render_template (строка)
Относительный или абсолютный путь к шаблону для вывода блока на фронтенде.
// Specifying a relative path within the active theme 'render_template' => 'template-parts/blocks/testimonial/testimonial.php', // Specifying an absolute path 'render_template' => plugin_dir_path( __FILE__ ) . 'template-parts/blocks/testimonial/testimonial.php',
render_callback (вызываемый, опционально)
Имя функции, которая выводит HTML блока. Можно использовать вместо render_template.
// Specifying a function 'render_callback' => 'my_acf_block_render_callback', // Specifying a class method 'render_callback' => array($this, 'block_render_callback'),
enqueue_style (строка, опционально)
URL до CSS файла со стилями блока. Подключается и на фронтенде и на бэкенде.
'enqueue_style' => get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.css',
enqueue_script (строка, опционально)
URL до JavaScript файла со скриптами блока. Подключается и на фронтенде и на бэкенде.
enqueue_script' => get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.js',
enqueue_assets (вызываемый, опционально)
Колбек функция, которая вызывается во время отображения блока и подключает стили и/или скрипты. Работает как на фронтенде, так и на бэкенде.
// Specifying a function name
'enqueue_assets' => 'my_acf_block_enqueue_assets',
// Specifying a class method
'enqueue_assets' => array($this, 'block_enqueue_assets'),
// Specifying an anonymouse function
'enqueue_assets' => function(){
wp_enqueue_style( 'block-testimonial', get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.css' );
wp_enqueue_script( 'block-testimonial', get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.js', array('jquery'), '', true );
},
supports (массив, опционально)
Включает/отключает поддержку некоторых возможностей для блока. Может принимать значения: align, mode и multiple.
// Отключить панель выравнивания. 'align' => false, // Настроить панель выравнивания. 'align' => array( 'left', 'right', 'full' ), // Отключить возможность выбора режима preview/edit. 'mode' => false, // Запретить множественную вставку блока. 'multiple' => false,
Примеры
Регистрация блока с шаблоном
Этот пример показывает, как зарегистрировать блок, используя настройку render_template:
functions.php:
function mihdan_register_blocks() {
// Проверяем, что функция доступна.
if( function_exists( 'acf_register_block_type' ) ) {
// Регистрируем блок рекомендаций.
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_template' => 'template-parts/blocks/testimonial/testimonial.php',
'category' => 'formatting',
));
}
}
add_action( 'acf/init', 'mihdan_register_blocks' );
template-parts/blocks/testimonial/testimonial.php
<?php
/**
* Testimonial Block Template.
*
* @param array $block The block settings and attributes.
* @param string $content The block inner HTML (empty).
* @param bool $is_preview True during AJAX preview.
* @param (int|string) $post_id The post ID this block is saved to.
*/
// Create id attribute allowing for custom "anchor" value.
$id = 'testimonial-' . $block['id'];
if( !empty($block['anchor']) ) {
$id = $block['anchor'];
}
// Create class attribute allowing for custom "className" and "align" values.
$className = 'testimonial';
if( !empty($block['className']) ) {
$className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
$className .= ' align' . $block['align'];
}
// Load values and assing defaults.
$text = get_field('testimonial') ?: 'Your testimonial here...';
$author = get_field('author') ?: 'Author name';
$role = get_field('role') ?: 'Author role';
$image = get_field('image') ?: 295;
$background_color = get_field('background_color');
$text_color = get_field('text_color');
?>
<div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>">
<blockquote class="testimonial-blockquote">
<span class="testimonial-text"><?php echo $text; ?></span>
<span class="testimonial-author"><?php echo $author; ?></span>
<span class="testimonial-role"><?php echo $role; ?></span>
</blockquote>
<div class="testimonial-image">
<?php echo wp_get_attachment_image( $image, 'full' ); ?>
</div>
<style type="text/css">
#<?php echo $id; ?> {
background: <?php echo $background_color; ?>;
color: <?php echo $text_color; ?>;
}
</style>
</div>
Регистрация блока при помощи колбека
Этот пример показывает, как зарегистрировать блок, используя настройку render_callback:
functions.php
add_action('acf/init', 'my_register_blocks');
function my_register_blocks() {
// check function exists.
if( function_exists('acf_register_block_type') ) {
// register a testimonial block.
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_callback' => 'my_acf_block_render_callback',
'category' => 'formatting',
));
}
}
/**
* Testimonial Block Callback Function.
*
* @param array $block The block settings and attributes.
* @param string $content The block inner HTML (empty).
* @param bool $is_preview True during AJAX preview.
* @param (int|string) $post_id The post ID this block is saved to.
*/
function my_acf_block_render_callback( $block, $content = '', $is_preview = false, $post_id = 0 ) {
// Create id attribute allowing for custom "anchor" value.
$id = 'testimonial-' . $block['id'];
if( !empty($block['anchor']) ) {
$id = $block['anchor'];
}
// Create class attribute allowing for custom "className" and "align" values.
$className = 'testimonial';
if( !empty($block['className']) ) {
$className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
$className .= ' align' . $block['align'];
}
// Load values and assing defaults.
$text = get_field('testimonial') ?: 'Your testimonial here...';
$author = get_field('author') ?: 'Author name';
$role = get_field('role') ?: 'Author role';
$image = get_field('image') ?: 295;
$background_color = get_field('background_color');
$text_color = get_field('text_color');
?>
<div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>">
<blockquote class="testimonial-blockquote">
<span class="testimonial-text"><?php echo $text; ?></span>
<span class="testimonial-author"><?php echo $author; ?></span>
<span class="testimonial-role"><?php echo $role; ?></span>
</blockquote>
<div class="testimonial-image">
<?php echo wp_get_attachment_image( $image, 'full' ); ?>
</div>
<style type="text/css">
#<?php echo $id; ?> {
background: <?php echo $background_color; ?>;
color: <?php echo $text_color; ?>;
}
</style>
</div>
<?php
}
Создание группы полей ACF
Через плагин ACF Pro заведите новую группу полей под названием Testimonal как показано на скриншоте и в условиях отображения выберите Блок = Testimonal.


Добавление стилей к блоку
functions.php
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_template' => get_template_directory() . '/template-parts/blocks/testimonial/testimonial.php',
'enqueue_style' => get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.css',
));
testimonial.php
<blockquote class="testimonial">
...
</blockquote>
testimonial.css
.testimonial {
background: #00e4ba;
color: #fff;
}
Добавление скриптов к блоку
functions.php
acf_register_block_type(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_template' => get_template_directory() . '/template-parts/blocks/testimonial/testimonial.php',
'enqueue_script' => get_template_directory_uri() . '/template-parts/blocks/testimonial/testimonial.js',
));
testimonial.php
<blockquote class="testimonial">
<img src="..." />
...
</blockquote>
testimonial.js
(function($){
/**
* initializeBlock
*
* Adds custom JavaScript to the block HTML.
*
* @date 15/4/19
* @since 1.0.0
*
* @param object $block The block jQuery element.
* @param object attributes The block attributes (only available when editing).
* @return void
*/
var initializeBlock = function( $block ) {
$block.find('img').doSomething();
}
// Initialize each block on page load (front end).
$(document).ready(function(){
$('.testimonial').each(function(){
initializeBlock( $(this) );
});
});
// Initialize dynamic block preview (editor).
if( window.acf ) {
window.acf.addAction( 'render_block_preview/type=testimonial', initializeBlock );
}
})(jQuery);