Как расширить блок галереи в Gutenberg?

19 мар. 2018 г., 11:12:40
Просмотры: 16.1K
Голосов: 17

Я экспериментирую с Gutenberg до его включения в ядро WordPress и хотел бы узнать, как расширить существующий блок галереи, чтобы изменить его отображение. Например, вместо сетки миниатюр я хочу показывать слайд-шоу из изображений. Возможно ли это? Если да, то как? Буду благодарен за любую помощь.

3
Комментарии

В Руководстве по Gutenberg есть глава о Расширяемости, которая может быть первым шагом, чтобы проверить, можно ли использовать фильтры из раздела Изменение блоков для этого случая.

birgire birgire
19 мар. 2018 г. 17:59:52

Похоже, эта глава была добавлена недавно. Раньше я её не видел. В любом случае, так как она помечена как экспериментальная, эта функция может измениться. Я подожду, пока она стабилизируется. Спасибо!

leemon leemon
20 мар. 2018 г. 00:18:21

Следующий документ более актуален: https://github.com/WordPress/gutenberg/blob/master/docs/extensibility.md

leemon leemon
20 мар. 2018 г. 13:55:22
Все ответы на вопрос 2
1
21

Хорошо, я немного поэкспериментировал с этим и смог изменить вывод блока Галереи, но с некоторыми оговорками:

  • Превью не соответствует выводу. Кажется, это возможно исправить, но требует более глубокой доработки.
  • Для корректной работы блока в выводе необходимы определённые классы и разметка, чтобы блок мог распарсить содержимое и оставить его редактируемым. Эти классы имеют фронтенд-стили, которые также нужно учитывать. Пока неясно, можно ли фильтровать, как блок это обрабатывает. Даже если это возможно, возможно, это не лучшая идея, так как Галереи могут сломаться при деактивации темы или плагина. Для таких случаев лучше создать полностью новый блок.
  • Пока не совсем понятно, как работают размеры изображений.
  • Используемые JavaScript-хуки могут измениться в финальной версии. Gutenberg использует @wordpress/hooks, но в ядре WordPress ещё идёт обсуждение, какую систему хуков использовать.
  • Поскольку вывод Блоков сохраняется как HTML, а не шорткод или метаданные, изменить вывод существующих Галерей без их редактирования не получится.

Первое, что нужно сделать — зарегистрировать скрипт. Это делается через wp_enqueue_scripts(), но на хуке enqueue_block_editor_assets.

Скрипт должен зависеть от wp-blocks. Он почти наверняка уже загружен в редакторе, но указание зависимости гарантирует, что он загрузится до нашего скрипта.

function wpse_298225_enqueue_block_assets() {
    wp_enqueue_script(
        'wpse-298225-gallery-block',
        get_theme_file_uri( 'block.js' ),
        ['wp-blocks']
    );
}
add_action( 'enqueue_block_editor_assets', 'wpse_298225_enqueue_block_assets' );

HTML для вывода блока обрабатывается методом save() блока. Вы можете увидеть метод save() блока Галереи в этом файле.

На текущий момент (март 2018) Gutenberg поддерживает фильтр для метода сохранения блоков — blocks.getSaveElement. Мы можем добавить хук в JavaScript вот так:

wp.hooks.addFilter(
    'blocks.getSaveElement',
    'wpse-298225',
    wpse298225GallerySaveElement
)

Первый аргумент — название хука, второй — пространство имён (кажется), а последний — функция обратного вызова.

Поскольку мы заменяем метод save() блока, нам нужно вернуть новый элемент. Однако это не обычный HTML-элемент, который нужно вернуть. Нам нужно вернуть элемент React.

Если посмотреть на оригинальный метод save() блока, вы увидите JSX. React, который использует Gutenberg, поддерживает его для рендеринга элементов. Подробнее об этом — в этой статье.

JSX обычно требует сборки, но поскольку я не добавляю этот шаг в примере, нам нужен способ создать элемент без JSX. React предоставляет такой метод — createElement(). WordPress оборачивает его и другую функциональность React в wp.element. Поэтому для использования createElement() мы пишем wp.element.createElement().

В функции обратного вызова для blocks.getSaveElement мы получаем:

  • element — оригинальный элемент, созданный блоком.
  • blockType — объект, представляющий используемый блок.
  • attributes — свойства экземпляра блока. В нашем примере это включает изображения в галерее и настройки, например количество колонок.

Таким образом, наша функция обратного вызова должна:

  • Вернуть оригинальный элемент для блоков, не являющихся галереями.
  • Взять атрибуты (особенно изображения) и создать новый React-элемент, представляющий галерею.

Вот полный пример, который просто выводит ul с классом my-gallery и li для каждого изображения с классом my-gallery-item, а внутри каждого — тег img с src, указывающим на URL изображения.

function wpse298225GallerySaveElement( element, blockType, attributes ) {
    if ( blockType.name !== 'core/gallery' ) {
        return element;
    }

    var newElement = wp.element.createElement(
        'ul',
        {
            'className': 'wp-block-gallery my-gallery',
        },
        attributes.images.map(
            function( image ) {
                return wp.element.createElement(
                    'li',
                    {
                        'className': 'blocks-gallery-item my-gallery-item',
                    },
                    wp.element.createElement(
                        'img',
                        {
                            'src': image.url,
                        }
                    )
                )
            }
        )
    )

    return newElement
}

Несколько важных моментов:

  • Оригинальный блок Галереи ищет изображения по селектору ul.wp-block-gallery .blocks-gallery-item, поэтому эта разметка и классы необходимы для редактирования блока. Эта разметка также используется для стилей по умолчанию.
  • attributes.images.map проходит по каждому изображению и возвращает массив дочерних элементов как содержимое основного элемента. Внутри этих элементов находится ещё один дочерний элемент для самого изображения.
21 мар. 2018 г. 11:57:19
Комментарии

Все связанные файлы возвращают ошибку 404.

TCB13 TCB13
16 июн. 2020 г. 14:29:14
2

Предоставляю обновленный ответ. Я нашел эту статью чрезвычайно полезной для ответа на вопрос о том, как расширить блок Gallery.

Коротко говоря, рекомендуется создать новый блок, а не расширять существующий. Из статьи по ссылке выше:

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

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

С помощью этих ресурсов я смог быстро разобраться, как разработать пользовательский блок галереи.

14 февр. 2019 г. 01:50:44
Комментарии

Есть ли у вас еще советы по созданию блока галереи? Мне кажется, что на стороне редактора предстоит значительный объем работ для поддержки всех необходимых CRUD-функций. Стандартное решение WordPress обрабатывает все: от загрузки изображений до их сортировки, добавления новых, удаления существующих и т. д. Насколько я понимаю, потребуется много работы, чтобы воссоздать ту же функциональность, которая идет "из коробки", просто для кастомизации фронтенда.

phip phip
5 февр. 2020 г. 04:06:47

@phip прошло около 6 месяцев с тех пор, как я глубоко погружался в блоки Gutenberg, и я знаю, что многое изменилось. Я согласен с тем, что вы говорите, если правильно вас понимаю. Действительно, создание пользовательских интерфейсов для управления CRUD-операциями казалось сложной задачей.

Версия Advanced Custom Fields Pro позволяет создавать пользовательские схемы данных для блоков. Подробнее можно узнать здесь: https://www.advancedcustomfields.com/resources/blocks/. Хотя мне понравилось изучать React для создания блоков, использование ACF значительно экономило время.

Jeff Wilkerson Jeff Wilkerson
7 февр. 2020 г. 23:29:45