Благодаря 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);