Как использовать InnerBlocks в блоках ACF

Моя любимая новая функция в 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 для указания текста-заполнителя. Он не будет опубликован, а при выборе поля этот плейсхолдер исчезнет.

У меня было две проблемы с заполнителями, поэтому я использовал вместо них содержимое по умолчанию:

  1. Когда вы вставляете блок, первый блок внутри InnerBlocks выбран, поэтому его текст-заполнитель не виден. Нужно вставить блок, а затем щелкнуть за пределами блока, чтобы увидеть текст заполнителя.
  2. Плейсхолдер не поддерживает 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/

Михаил Кобзарёв

Суровый русский тимлид. Жил в Магадане, в офисе московских веб студий и в Тульской деревне. Виртуозно знает WordPress, PHP, ООП, Vue.js и вот это вот все. Делает крутые высоконагруженные сайты, поэтому уже почти захватил весь рынок WordPress разработки в России. Не дает никому делать сайты без спроса. Ведет блог о разработке, дайджест в телеграмме и в ВК. Любит сиськи, баню и радиоэлектронику. 100% патриот (но это не точно). Тролль 542 уровня. Ездит в отпуск раз в 5 лет.

Добавить комментарий

%d такие блоггеры, как: