К Gutenberg есть функция, позволяющая из обычного текста «распаковывать блок» в массив с параметрами. И это функция parse_blocks()
.
parse_blocks( $content )
Прежде, чем мы перейдём к примерам, хочу порекомендовать вам свой видеокурс по созданию блоков Gutenberg!
Например первые два абзацы этого урока в разметке выглядит вот так:
<!-- 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> ) ) )
Это может оказаться полезным, например при выводе содержания из заголовков автоматически, рассмотрим это в следующем примере.
Небольшая подготовительная работа – добавьте на заголовки, которые вы хотите, чтобы были в содержании HTML-якорь:
/** * @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>'; }
truemisha_get_id_from_h_tag()
, которая позволяет получить ID из тега. Кстати! Если знаете решение через регулярные выражения, буду рад, если оставите в комментариях.core/heading
– это ярлык/идентификатор блоков с заголовками.empty( $block[ 'attrs' ][ 'level' ] )
– она означает, что нам нужны заголовки только второго уровня, так как у них нет этого атрибута, у всех остальных он является цифров, например level
заголовка h3
равен чему? Ну 3
конечно же! 😁Чтобы оставить комментарий, пожалуйста, зарегистрируйтесь или войдите.
Есть косяк с парсингом реюзабельных блоков - там не получить название, будет core/block для любого
Час добрый, Михаил!
Во первых — спасибо за ресурс. Много полезного для себя подчерпнул. Держать планку и не падать ниже достигнутого!
Во-вторых — не знаю будет ли уместен мой вопрос именно в этом посте, но, как мне показалось, он ближе всего к теме моего вопроса.
Странное поведение обнаружил у WP (отсечь с какого обновления это началось уже не смогу).
При любой попытке вставить в редакторе заголовок любого уровня, автоматом заполняется поле якоря, которое полностью повторяет текст заголовка. Попытка сделать это поле пустым ничего не дает и он заполняется снова.
Это нормально?
А если мне это не нужно, то как мне от этого избавиться. У меня заголовок в три строки — и он мне шарашит в id="все-три-строки-причем-по-русски". Как мне убрать такое поведение WP? Раньше такого не было.
Спасибо!
Добрый день, Дмитрий,
спасибо большое!
Нет, это ни разу не нормально.
На данный момент могу рекомендовать откатиться на предыдыдущую версию. Я ожидаю, что в следующей версии это уберут.
Следить за обсуждением этого момента можно тут https://github.com/WordPress/gutenberg/issues/38171