Верх страницы
Обложка к записи Как отфильтровать контент блока в WordPress
Время для прочтения: 1 мин. 36 сек.

Как отфильтровать контент блока в WordPress

WordPress предоставляет два хука для фильтрации содержимого отдельных блоков. Рассмотрим, как их использовать, в этой небольшой статье.

Краткое введение

Каждый раз, когда запись отображается во фронтенде, функция render_block() генерирует HTML блока, начиная с объекта block.

Данная функция включает в себя следующие фильтры:

В конце этой функции объект блока парсится с помощью метода render() класса class-wp-block.php. Внутри этого метода применяются два фильтра. Это фильтры render_block и render_block_{$this->name}.

Эти два фильтра похожи друг на друга. Фильтр render_block подключает функцию ко всем блокам, входящим в запись, а фильтр render_block_{$this->name} подключает только блоки указанного типа.

Фильтр render_block

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

Пример 1: Модификация блока на основе значения атрибута блока

С помощью этого фильтра можно модифицировать блоки на основе значений определенных атрибутов блока.

В приведенном ниже примере, когда атрибут hideBlock произвольного блока равен 1, вместо HTML блока возвращается пустая строка.

/**
 * When the "hideBlock" custom block attribute is equal to "1" an empty string is returned.
 *
 * @param $block_content
 * @param $block
 * @return string
 */
function hide_selected_blocks( string $block_content, array $block ): string {

    if ( isset($block['attrs']['hideBlock']) and $block['attrs']['hideBlock'] === 1 ) {

        return '';

    } else {

        return $block_content;

    }

}

add_filter( 'render_block', 'hide_selected_blocks', 10, 2 );

Этот прием мы использовали при разработке Restricted Blocks, плагина, который накладывает ограничения на определенные блоки на основе пользовательских условий. В этом плагине пользователь задает тип ограничения с помощью селектора, сохраняемого как атрибут блока. Затем плагин использует фильтр render_block для чтения этого атрибута блока и соответствующего изменения содержимого блока.

Пример 2: Изменение только определенных типов блоков

Во втором примере мы добавим рекламный блок перед каждым заголовком статьи. Чтобы определить тип блока, мы проверяем значение $block['blockName'].

/**
 * An ad is applied before the blocks of type "core/heading".
 *
 * @param $block_content
 * @param $block
 * @return mixed|string
 */
function include_ad_before_heading( string $block_content, array $block ): string {

    if ( $block['blockName'] === 'core/heading' ) {

        return '<div class="my-ad"></div>' . $block_content;

    } else {

        return $block_content;

    }

}

add_filter( 'render_block', 'include_ad_before_heading', 10, 2 );

Фильтр render_block_{$this->name}

Этот динамический фильтр позволяет подключить функцию, изменяющую блоки определенного типа.

Имя этого фильтра состоит из фиксированной части render_block_, за которой следует переменная часть с именем блока. Например, core/paragraph, core/image, plugin-name/custom-block и т.д.

Стоит отметить, что данный фильтр был добавлен ещё в версии WordPress 5.7. Дополнительные подробности можно найти в официальном сообщении.

Пример 1: Удаление всех изображений из записи

В данном примере мы используем хук render_block_core/image для скрытия всех изображений, входящих в статью.

Для всех блоков, зарегистрированных как core/image, вызывается функция hide_images(), которая всегда возвращает пустую строку. Как следствие, HTML всех изображений будет удален из записи.

/**
 * This function runs only with blocks of type "core/image" and returns an empty string.
 *
 * @param $block_content
 * @param $block
 * @return string
 */
function hide_images( string $block_content, array $block ): string {
    return '';
}

add_filter( 'render_block_core/image', 'hide_images', 10, 2 );

Пример 2: Сбор данных о всех заголовках

В этом примере с помощью регулярного выражения мы собираем данные о заголовках в глобальную переменную. В дальнейшем собранные данные могут быть использованы для создания автоматического оглавления или для других целей.

Для фильтрации всех блоков с заголовками используется хук render_block_core/heading.

/**
 * This function runs only with blocks of type "core/heading". The headings data are collected in the $headings_data
 * array.
 *
 * Note that the function always returns a string with the original block content.
 *
 * @param $block_content
 * @param $block
 * @return string
 */
function collect_headings_data( string $block_content, block $block ): string {

    global $headings_data;
    $matches = [];

    preg_match( '/<(h[1-6]{1}).*id="(.+)".*>(.*?)<\/h[1-6]{1}>/', $block['innerHTML'], $matches );

    if (count($matches) === 4 ) {
        $headings_data[] = [
            'tag' => $matches[1],
            'anchor' => $matches[2],
            'text' => $matches[3]
        ];
    }

    return $block_content;

}

add_filter( 'render_block_core/heading', 'collect_headings_data', 10, 2 );

Выводы

Надеюсь, этот урок помог вам в фильтрации содержимого отдельных блоков.

Для получения более подробной информации по этому вопросу я рекомендую ознакомиться с ядром WordPress, в частности, со следующими файлами:

  • wp-includes/class-wp-block.php
  • wp-includes/blocks.php

Источник: Filter the content of single blocks with WordPress

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

Русский разработчик с 20-ти летним стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Битрикс, Joomla, Drupal, OpenCart, DLE, Laravel, Moonshine, Symfony, SuiteCRM.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

Комментарии
Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Предыдущая запись

Давайте дружить
в Telegram

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Laravel, Moonshine, фильмы и сериалы