do_blocks()WP 5.0.0

Преобразует указанную строку c разметкой Gutenberg-блоков в готовый HTML, последовательно парся и рендеря каждый блок.

Функция проходит по содержимому, создаёт дерево блоков через parse_blocks(), а затем выводит HTML каждого блока, вызывая render_block(). Таким образом вы получаете HTML блоков, но в любом нужном месте — например, при выводе данных из метаполей или REST API.

Функция по умолчанию висит на хуке the_content:

add_filter( 'the_content', 'do_blocks', 9 );

Если передать строку, где нет комментариев <!-- wp:... -->, функция вернёт исходный текст без изменений.

Работает на основе: parse_blocks(), render_block()
1 раз — 0.0066509 сек (очень медленно) | 50000 раз — 30.33 сек (очень медленно) | PHP 8.2.25, WP 6.8.1

Хуков нет.

Возвращает

Строку. Отрендерённый HTML-контент.

Использование

do_blocks( $content );
$content(string) (обязательный)
Сырой контент в блок-нотации Gutenberg: <!-- wp:paragraph -->…<!-- /wp:paragraph -->.

Примеры

0

#1 Используем в REST API-эндпойнте

Возвращаем HTML блоков вместо сырой разметки.

register_rest_field( 'post', 'blocks_html', [
	'get_callback' => fn( $post_arr ) => do_blocks( $post_arr['content']['raw'] ),
] );
-1

#2 Демо

$block_content = do_blocks(
	<<<'HTML'
	<!-- wp:group {"layout":{"type":"constrained"}} -->
	<div class="wp-block-group">
		<!-- wp:heading {"level":2} -->
		<h2>Пример заголовка</h2>
		<!-- /wp:heading -->

		<!-- wp:paragraph -->
		<p>Это демонстрационный параграф. Он будет отображён так же, как в редакторе.</p>
		<!-- /wp:paragraph -->

		<!-- wp:image {"sizeSlug":"large"} -->
		<figure class="wp-block-image size-large">
			<img src="https://via.placeholder.com/1024x512" alt="Placeholder" />
		</figure>
		<!-- /wp:image -->
	</div>
	<!-- /wp:group -->
	HTML
);

echo $block_content;

Получим:

<div class="wp-block-group">
	<div class="wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained">
		<h2 class="wp-block-heading">Пример заголовка</h2>

		<p>Это демонстрационный параграф. Он будет отображён так же, как в редакторе.</p>

		<figure class="wp-block-image size-large">
			<img src="https://via.placeholder.com/1024x512" alt="Placeholder"/>
		</figure>
	</div>
</div>

Список изменений

С версии 5.0.0 Введена.

Код do_blocks() WP 6.9

function do_blocks( $content ) {
	$blocks                = parse_blocks( $content );
	$top_level_block_count = count( $blocks );
	$output                = '';

	/**
	 * Parsed blocks consist of a list of top-level blocks. Those top-level
	 * blocks may themselves contain nested inner blocks. However, every
	 * top-level block is rendered independently, meaning there are no data
	 * dependencies between them.
	 *
	 * Ideally, therefore, the parser would only need to parse one complete
	 * top-level block at a time, render it, and move on. Unfortunately, this
	 * is not possible with {@see \parse_blocks()} because it must parse the
	 * entire given document at once.
	 *
	 * While the current implementation prevents this optimization, it’s still
	 * possible to reduce the peak memory use when calls to `render_block()`
	 * on those top-level blocks are memory-heavy (which many of them are).
	 * By setting each parsed block to `NULL` after rendering it, any memory
	 * allocated during the render will be freed and reused for the next block.
	 * Before making this change, that memory was retained and would lead to
	 * out-of-memory crashes for certain posts that now run with this change.
	 */
	for ( $i = 0; $i < $top_level_block_count; $i++ ) {
		$output      .= render_block( $blocks[ $i ] );
		$blocks[ $i ] = null;
	}

	// If there are blocks in this content, we shouldn't run wpautop() on it later.
	$priority = has_filter( 'the_content', 'wpautop' );
	if ( false !== $priority && doing_filter( 'the_content' ) && has_blocks( $content ) ) {
		remove_filter( 'the_content', 'wpautop', $priority );
		add_filter( 'the_content', '_restore_wpautop_hook', $priority + 1 );
	}

	return $output;
}