Моя любимая новая функция в Advanced Custom Fields 5.9 — поддержка InnerBlocks. Это позволяет вам вставлять любой блок (из ядра или пользовательский) внутрь блока ACF.
Вместо того чтобы создавать собственные поля для Title, Content и Button в пользовательском блоке, вы можете просто вставить <InnerBlocks />
и использовать редактор блоков для создания содержимого внутри блока.
Как использовать InnerBlocks
При регистрации собственного блока ACF, добавьте 'jsx' => true
в массив supports
.
acf_register_block_type( array(
'title' => __( 'About', 'client_textdomain' ),
'name' => 'about',
'render_template' => 'partials/blocks/about.php',
'mode' => 'preview',
'supports' => [
'align' => false,
'anchor' => true,
'customClassName' => true,
'jsx' => true,
],
) );
В шаблоне для вашего блока добавьте тег <InnerBlocks />
, в том месте, где вы хотите, чтобы появилась область добавления дочерних блоков.
$classes = [ 'block-about' ];
if ( ! empty( $block['className'] ) ) {
$classes = array_merge( $classes, explode( ' ', $block['className'] ) );
}
$anchor = '';
if ( ! empty( $block['anchor'] ) ) {
$anchor = ' id="' . sanitize_title( $block['anchor'] ) . '"';
}
echo '<div class="' . join( ' ', $classes ) . '"' . $anchor . '>';
echo '<div class="block-about__inner">';
echo '<div class="block-about__content">';
echo '<InnerBlocks />';
echo '</div>';
echo '<div class="block-about__image">';
echo wp_get_attachment_image( get_field( 'image' ), 'be_thumbnail_l' );
echo '</div>';
echo '</div>';
echo '</div>';
Значение по умолчанию для InnerBlocks
Полезно заполнить поле InnerBlocks содержимым по умолчанию, чтобы блок выглядел правильно при первой вставке.
Недавно мы создавали новый сайт для компании Nice Kicks, и им часто нужно было сообщать дату выхода и подробности о новых кроссовках. Мы создали блок Release Info, который использует InnerBlocks для области содержимого.
Вместо пустого белого поля, когда они впервые вставляют блок, мы предварительно заполняем его содержимым по умолчанию с помощью шаблона блока.
Внутри файла шаблона блока создайте массив $template
, в котором подробно опишите, какие блоки должны быть добавлены. Обновите <InnerBlocks />
, чтобы включить новый шаблон.
Доступные атрибуты блока можно найти в файле blocks.json для каждого блока в wp-includes/blocks.
$template = array(
array(
'core/heading',
array(
'level' => 2,
'content' => 'Title Goes Here',
),
),
array(
'core/paragraph',
array(
'content' => '<strong>Colorway:</strong> <br /><strong>Style Code:</strong> <br /><strong>Release Date:</strong> <br /><strong>MSRP:</strong> ',
),
),
);
echo '<div class="' . join( ' ', $classes ) . '"' . $anchor . '>';
echo '<InnerBlocks template="' . esc_attr( wp_json_encode( $template ) ) . '" />';
$form_id = get_option( 'options_be_release_info_form' );
if ( ! empty( $form_id ) && function_exists( 'wpforms_display' ) ) {
wpforms_display( $form_id, true, true );
}
echo '</div>';
Плейсхолдеры вместо содержимого по умолчанию
В приведенном выше примере мы задали начальное содержание блока. Если бы вы опубликовали пост без изменения текста, в блоках появилось бы содержимое по умолчанию.
В качестве альтернативы можно использовать параметр placeholder
для указания текста-заполнителя. Он не будет опубликован, а при выборе поля этот плейсхолдер исчезнет.
У меня было две проблемы с заполнителями, поэтому я использовал вместо них содержимое по умолчанию:
- Когда вы вставляете блок, первый блок внутри InnerBlocks выбран, поэтому его текст-заполнитель не виден. Нужно вставить блок, а затем щелкнуть за пределами блока, чтобы увидеть текст заполнителя.
- Плейсхолдер не поддерживает HTML. В моем примере мы использовали
<strong>
и<br />
для форматирования текста абзаца, но это не работает с заполнителем.
Чтобы использовать заполнители в приведенном выше примере, измените $template
на:
$template = array(
array(
'core/heading',
array(
'level' => 2,
'placeholder' => 'Title Goes Here',
),
),
array(
'core/paragraph',
array(
'placeholder' => '<strong>Colorway:</strong> <br /><strong>Style #:</strong> <br /><strong>Release Date:</strong> <br /><strong>Price:</strong> ',
),
),
);
И вот такой кривой был результат:
Ограничение использования блоков в InnerBlocks
Вы можете указать, какие блоки могут быть вставлены в поле InnerBlocks, используя атрибут allowedBlocks
.
Using the example above, I can limit the Release Info block to only include the heading and paragraph blocks:
Используя приведенный выше пример, я могу ограничить использование блоков внутри Release Info только заголовками и абзацев:
$allowed_blocks = array( 'core/heading', 'core/paragraph' );
$template = array(
array(
'core/heading',
array(
'level' => 2,
'content' => 'Title Goes Here',
),
),
array(
'core/paragraph',
array(
'content' => '<strong>Colorway:</strong> <br /><strong>Style Code:</strong> <br /><strong>Release Date:</strong> <br /><strong>MSRP:</strong> ',
),
),
);
echo '<div class="' . join( ' ', $classes ) . '"' . $anchor . '>';
echo '<InnerBlocks allowedBlocks="' . esc_attr( wp_json_encode( $allowed_blocks ) ) . '" template="' . esc_attr( wp_json_encode( $template ) ) . '" />';
$form_id = get_option( 'options_be_release_info_form' );
if ( ! empty( $form_id ) && function_exists( 'wpforms_display' ) ) {
wpforms_display( $form_id, true, true );
}
echo '</div>';
Блокировка шаблона в InnerBlocks
Вы также можете ограничить гибкость, заблокировав шаблон.
Добавление templateLock="all"
предотвращает вставку новых блоков или удаление/переупорядочивание текущих блоков.
Добавление templateLock="insert"
предотвращает вставку новых блоков или удаление текущих блоков, но вы можете изменять расположение текущих блоков.
Недавно я создал блок Icon Heading. Иконка может быть выбрана в боковой панели настроек блока с помощью динамического выпадающего поля.
Я использовал InnerBlocks для самого заголовка, чтобы он имел все стандартные опции для настройки заголовка (стиль блока, тип заголовка). Я использовал templateLock="all"
, чтобы в этом блоке можно было использовать только заголовок из шаблона блока.
$classes = [ 'block-icon-heading' ];
if ( ! empty( $block['className'] ) ) {
$classes = array_merge( $classes, explode( ' ', $block['className'] ) );
}
if ( ! empty( $block['align'] ) ) {
$classes[] = 'align' . $block['align'];
}
$anchor = '';
if ( ! empty( $block['anchor'] ) ) {
$anchor = ' id="' . sanitize_title( $block['anchor'] ) . '"';
}
$template = array(
array(
'core/heading',
array(
'level' => 2,
'content' => 'Heading',
),
),
);
echo '<div class="' . join( ' ', $classes ) . '"' . $anchor . '>';
$icon = get_field( 'dynamic_icon_category' );
if ( ! empty( $icon ) ) {
echo '<div class="icon-heading-wrap">' . be_icon( [ 'icon' => $icon, 'group' => 'category', 'size' => 38 ] ) . '</div>';
}
echo '<InnerBlocks template="' . esc_attr( wp_json_encode( $template ) ) . '" templateLock="all" />';
echo '</div>';
Источник: InnerBlocks with ACF blocks.
Источник: https://www.kobzarev.com/wordpress/innerblocks-with-acf-blocks/