Парсим блоки Gutenberg в PHP. Создаём содержание из заголовков

К Gutenberg есть функция, позволяющая из обычного текста «распаковывать блок» в массив с параметрами. И это функция parse_blocks().

parse_blocks( $content )
$content
(строка) какой-то контент, содержащий блоки внутри.

Прежде, чем мы перейдём к примерам, хочу порекомендовать вам свой видеокурс по созданию блоков Gutenberg!

Пример 1

Например первые два абзацы этого урока в разметке выглядит вот так:

<!-- wp:paragraph -->
<p>К Gutenberg есть функция, позволяющая из обычного текста "распаковывать блок" в массив с параметрами. И это функция <code>parse_blocks()</code>.</p>
<!-- /wp:paragraph -->
 
<!-- wp:misha/code -->
<div class="wp-block-misha-code"><pre lang="php">parse_blocks( $content )</pre></div>
<!-- /wp:misha/code -->

Если же мы пропустим это через функцию parse_blocks(), $blocks = parse_blocks( $post->post_content ), то в итоге у нас будет:

Array
(
    [0] => Array
        (
            [blockName] => core/paragraph
            [attrs] => Array
                (
                )
 
            [innerBlocks] => Array
                (
                )
 
            [innerHTML] => 
<p>К Gutenberg есть функция, позволяющая из обычного текста "распаковывать блок" в массив с параметрами. И это функция <code>parse_blocks()</code>.</p>
 
            [innerContent] => Array
                (
                    [0] => 
<p>К Gutenberg есть функция, позволяющая из обычного текста "распаковывать блок" в массив с параметрами. И это функция <code>parse_blocks()</code>.</p>
 
                )
 
        )
 
    [1] => Array
        (
            [blockName] => 
            [attrs] => Array
                (
                )
 
            [innerBlocks] => Array
                (
                )
 
            [innerHTML] => 
 
 
            [innerContent] => Array
                (
                    [0] => 
 
 
                )
 
        )
 
    [2] => Array
        (
            [blockName] => misha/code
            [attrs] => Array
                (
                )
 
            [innerBlocks] => Array
                (
                )
 
            [innerHTML] => 
<div class="wp-block-misha-code"><pre lang="php">parse_blocks( $content )</pre></div>
 
            [innerContent] => Array
                (
                    [0] => 
<div class="wp-block-misha-code"><pre lang="php">parse_blocks( $content )</pre></div>
 
                )
 
        )
 
)

Это может оказаться полезным, например при выводе содержания из заголовков автоматически, рассмотрим это в следующем примере.

Пример 2. Содержание из заголовков

Небольшая подготовительная работа – добавьте на заголовки, которые вы хотите, чтобы были в содержании HTML-якорь:

HTML-якорь заголовков в Gutenberg
/**
 * @snippet       Создание содержания из заголовков в Gutenberg
 * @author        Миша Рудрастых
 * @url           https://misha.agency/gutenberg/parse_blocks.html
 */
// сначала вынесу отдельную функцию, которая поможет нам получить ID из тегов заголовка
function truemisha_get_id_from_h_tag( $html_string, $heading_lvl = 'h2' ) {
 
	$doc = new DOMDocument();
	$doc->loadHTML( $html_string );
	$tags = $doc->getElementsByTagName( $heading_lvl );
	return $tags[0]->getAttribute('id');
 
}
 
// окей сначала парсим функцией контент текущей записи
global $post;
$blocks = parse_blocks( $post->post_content );
 
// в этот массив будем записывать заголовки
$headings = array();
 
// запускаем массив блоков в цикле
foreach( $blocks as $block ) {
 
	// если это блок-заголовок, то добавляем его в общий массив
	if( 'core/heading' === $block[ 'blockName' ] && empty( $block[ 'attrs' ][ 'level' ] ) ) {
		if( $id = truemisha_get_id_from_h_tag( $block[ 'innerHTML' ] ) ) {
			$headings[ $id ] = wp_strip_all_tags( $block[ 'innerHTML' ] );
		}
	}
 
}
 
// окей, у нас есть массив всех заголовков! 
if( ! empty( $headings ) ) {
	echo '<ol class="table-of-contents">';
	foreach( $headings as $id => $text ) {
		echo '<li><a href="#' . $id . '">' . $text . '</li>';
	}
	echo '</ol>';
}
  • Так нам не нужен просто список из заголовков, нам нужны также и HTML-якоря для переходов по содержанию, то в самом начале я добавил функцию truemisha_get_id_from_h_tag(), которая позволяет получить ID из тега. Кстати! Если знаете решение через регулярные выражения, буду рад, если оставите в комментариях.
  • core/heading – это ярлык/идентификатор блоков с заголовками.
  • Обратите внимание на проверку empty( $block[ 'attrs' ][ 'level' ] ) – она означает, что нам нужны заголовки только второго уровня, так как у них нет этого атрибута, у всех остальных он является цифров, например level заголовка h3 равен чему? Ну 3 конечно же! 😁
  • Также можете почитать про функцию wp_strip_all_tags().

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Если вам нужна помощь с сайтом или разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда будем рады вам помочь!

Комментарии — 1

Оставить комментарий

Если вы хотите добавить код, не забудьте обернуть его в <pre lang="php"></pre>, если же код – меньше одной строчки, то можно и в <code></code>.