✅ Новости WEB и WordPress, темы, плагины. Здесь мы делимся советами и лучшими решениями для веб-сайтов.

Добавьте пользовательские настройки к существующим блокам WordPress Gutenberg

109

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

Имейте в виду, что, поскольку блоки Гутенберга представляют собой Javascript, для их изменения требуется, чтобы вы написали код на Javascript. Точно так же, как PHP-код WordPress имеет хуки и фильтры, которые позволяют разработчикам тем или плагинов изменять его код, в коде WordPress Javascript также есть фильтры. Подобно [add_filter](https://developer.wordpress.org/reference/functions/add_filter/)()функции PHP, у нас есть функция Javascript [addFilter](https://developer.wordpress.org/block-editor/packages/packages-hooks/#api-usage)().

Я буду писать код в синтаксисе Javascript ES6, для преобразования которого требуется компилятор. Вы можете писать в синтаксисе ES5, но я рекомендую использовать ES6/ESNext. У меня есть пост, в котором объясняется, как настроить трансформатор для ES6/ESNext. Я также предполагаю, что у вас есть некоторое знакомство с React/JSX, возможно, некоторый опыт создания собственных пользовательских блоков Gutenberg.

Что вы можете фильтровать в блоках Гутенберга

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

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

  • Мы добавляем фильтр в [registerBlockType](https://developer.wordpress.org/block-editor/developers/block-api/block-registration/#registerblocktype)массив настроек существующего блока. Это позволяет нам добавлять новые атрибуты в attributesмассив, что позволяет нам сохранять дополнительную информацию в блоке. Нам нужно где-то сохранить наши пользовательские настройки.
  • Подцепите editкомпонент блока (компонент, отвечающий за рендеринг блока в редакторе). В этом хуке мы можем зацепиться за Инспектор (боковую панель) и добавить свои собственные компоненты. Мы можем либо добавить новый раздел/панель, либо мы можем подключиться к разделу «Дополнительно», который всегда присутствует во всех блоках. Затем нам нужно отобразить входные данные настроек, такие как ввод текста, флажки или что-то еще.
  • saveОтфильтруйте реквизиты блока. Мы можем настроить реквизиты для сохранения, которые отвечают как за сохранение блока, так и за его рендеринг во внешнем интерфейсе (вне редактора). В нашем случае мы хотим добавить класс или встроенный стиль.

Мы можем настроить таргетинг на определенные блоки или на все. У нас всегда есть доступ к типу блока, в котором мы находимся.

Другими словами: мы добавляем некоторые пользовательские настройки в Инспекторе и сохраняем их в пользовательских атрибутах, которые мы добавили в блок. Затем мы можем повлиять на имя класса блока или встроенный стиль (в некоторых случаях), в зависимости от сохраненных атрибутов. С помощью пользовательских имен классов мы можем легко добавить пользовательский CSS, который визуально придает эффект нашим настройкам.

Что мы не можем сделать (пока?)

К сожалению, есть некоторые вещи, к которым мы не можем получить доступ с помощью фильтров в существующих блоках. Что касается добавления простых пользовательских настроек в блоки, это обычные вещи, на которые мы не можем повлиять.

Нет доступа к встроенному стилю блока внутри редактора

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

К сожалению, кажется, что блоки WordPress по умолчанию обрабатывают встроенный стиль в редакторе совершенно независимо, без возможности фильтрации или «подключения». Я покажу способ обойти это в последнем примере ниже, но он не идеален во всех случаях.

Вы спросите, зачем заботиться о том, чтобы блок выглядел по-разному в редакторе и во внешнем интерфейсе? Весь смысл Гутенберга в том, чтобы реализовать визуальный способ редактирования контента, при котором то, что мы видим, на самом деле является тем, что мы получаем. Мы хотим добиться одинакового внешнего вида как в редакторе, так и во внешнем интерфейсе.

Некоторые блоки не содержат имя класса в редакторе.

Как упоминалось выше, мы можем отфильтровать имя класса упаковки блока, так как это реквизит, который передается всем блокам Гутенберга. Но, к сожалению, есть некоторые блоки, которые вообще не применяют класс блока в edit. Одним из примеров является блок Cover. Я много экспериментировал с использованием блоков Cover в качестве «разделов» для первых страниц и продолжаю сталкиваться с проблемами, потому что блок Cover строит свой собственный класс внутри edit. Он полностью пропускает, включая «глобальный» класс блока (к которому у нас есть доступ через фильтры).

Но, по крайней мере, мы можем быть уверены, что отфильтрованные имена классов всегда применяются в save(внешнем интерфейсе). Это происходит автоматически за пределами конкретного кода каждого блока.

Если я ошибаюсь в чем-либо из вышеперечисленного, ПОЖАЛУЙСТА, дайте мне знать в комментариях ниже! Я постоянно изучаю Гутенберг, и в то же время Гутенберг тоже развивается. Я надеюсь, что в какой-то момент вышеперечисленное станет возможным в какой-то момент или что это возможно, но мне просто не хватает важной информации!

С этим покончено, давайте начнем изучать код.

Пример 1. Добавьте поле переключения, чтобы скрыть блок обложки на мобильном устройстве.

Предположим, мы разрабатываем тему, в которой блоки обложки будут использоваться для «разделов» на главной странице. И мы хотим предоставить пользователю возможность скрыть определенный раздел с мобильного. Чтобы решить эту проблему, мы можем добавить поле переключения в разделе «Дополнительно» в инспекторе блока «Обложка». Если поле включено, блок Cover получит дополнительный пользовательский класс, на который мы можем ориентироваться с помощью CSS и медиа-запросов.

Кстати: это тот случай, когда проблема с блоком Cover, не применяющим наши пользовательские имена классов в редакторе, на самом деле является преимуществом! Представьте, если бы это произошло; тогда пользователь не сможет редактировать блок в редакторе, если у него маленький экран!

Как упоминалось ранее, нам нужно закодировать три шага. Нам также нужно добавить немного PHP, чтобы поставить наш файл Javascript в очередь в редакторе. Давайте сделаем это в первую очередь.

Добавляем наш скрипт в редактор

Мы подключаем функцию к действию [enqueue_block_editor_assets](https://developer.wordpress.org/reference/hooks/enqueue_block_editor_assets/). Внутри нашей функции мы помещаем скрипт в очередь, как обычно делаем это в wp_enqueue_scriptsхуке.

add_action('enqueue_block_editor_assets', function() { wp_enqueue_script('awp-gutenberg-filters', get_template_directory_uri(). '/assets/js/gutenberg-filters.js', ['wp-edit-post']); });

Не забудьте настроить путь к тому месту, где находится ваш скрипт! Примечание. Если вы пишете на ES6 с веб-пакетом, компилирующим ваш Javascript, не забудьте указать путь к сборке вашего скрипта, а не исходный код.

Мне нравится добавлять ‘ wp-edit-post‘ в качестве зависимости к сценарию, чтобы он загружался достаточно поздно.

Это весь PHP, который нам нужно сделать. Остальное написано в нашем файле Javascript.

Добавить настраиваемый атрибут

Первый фильтр, который мы будем использовать, — это объект настроек blocks.registerBlockTypeфильтров .registerBlockType

Но сначала немного о добавлении фильтров в Javascript. Поскольку я не нашел хорошей документации для этого, я немного объясню здесь. Функция addFilterнаходится в wp.hooksпространстве имен и принимает четыре аргумента.

addFilter('hookName', 'namespace', 'functionName', 'priority');

Первый параметр, «hookName», — это имя фильтра, к которому мы хотим подключиться. Это эквивалентно первому параметру при использовании PHP add_filter(). Второй параметр, «пространство имен», представляет собой пользовательское имя пространства имен для вашего кода. Это просто для того, чтобы избежать конфликта имен. Вы можете установить здесь все, что захотите, просто не используйте пространство имен WordPress («wp»). Используйте краткую форму своего имени или названия проекта. Третий параметр, ‘имя_функции’, представляет собой перехваченную функцию, аналогичную add_filter()второму аргументу PHP. И, наконец, четвертый параметр, «приоритет», является необязательным. Опять же, это то же самое, что add_filter()и третий аргумент PHP.

Процесс для фильтров в Javascript такой же, как и в PHP. Мы определяем функцию, которая должна возвращать отфильтрованную переменную. Иногда переменная представляет собой строку, объект или компонент. Внутри функции мы модифицируем переменную по своему усмотрению.

В нашем случае мы хотим добавить новый атрибут к attributeобъекту блока. Мы назовем новый атрибут hideOnMobileи установим его тип в boolean. Делается это так:

function addCoverAttribute(settings, name) { if (typeof settings.attributes !== 'undefined') { if (name == 'core/cover') { settings.attributes = Object.assign(settings.attributes, { hideOnMobile: { type: 'boolean', } }); } } return settings; }   wp.hooks.addFilter( 'blocks.registerBlockType', 'awp/cover-custom-attribute', addCoverAttribute );

В строке #3мы удостоверяемся, что нацелены только на блоки типа ‘ core/cover‘. Вторым аргументом для blocks.registerBlockTypeфильтрации достаточно удобно называть имя блока. Затем мы добавляем новый элемент объекта к settings.attributesобъекту. Наконец, мы обязательно возвращаем отфильтрованную переменную settings.

На данный момент визуально в Гутенберге ничего не меняется. Но все блоки Cover теперь имеют дополнительный атрибут, который мы можем использовать для хранения наших настроек.

Добавить настройку в Инспектор (панель «Дополнительно»)

Второй фильтр вызывается и фильтрует компонент editor.BlockEditблока. editЭтот фильтр получает BlockEditкомпонент исходного блока и возвращает новый упакованный компонент. Нам нужно использовать wp.compose.createHigherOrderComponentдля возврата обернутого компонента.

Внутри нашего компонента мы обязательно визуализируем обернутый компонент BlockEdit, независимо от того. Но если блок имеет тип Cover, мы также подключаемся к компоненту InspectorAdvancedControls(это панель «Дополнительно» в Inspector) и добавляем файл ToggleControl. Мы пишем, ToggleControlчтобы показать значение и обновить добавленный ранее настраиваемый атрибут hideOnMobile.

Не забывайте всегда возвращать оригинал BlockEdit, что мы и делаем в строке #9. В строке №10 мы проверяем, является ли блок типом Cover, и визуализируем InspectorAdvancedControlsкомпонент. Здесь мы добавляем ToggleControl, который представляет собой элемент управления вводом, который отображается как переключатель между true и false. Мы устанавливаем метку и связываем ее значение с hideOnMobileатрибутом. Если вы ранее добавляли настройки в Inspector, это должно быть довольно просто для вас.

С помощью приведенного выше кода мы должны теперь получить это внутри панели «Дополнительно» в инспекторе на блоках обложки:

Добавьте пользовательские настройки к существующим блокам WordPress Gutenberg

Ввод теперь будет обновлять наш пользовательский атрибут hideOnMobile. Последний шаг — сделать что-то в зависимости от значения этого атрибута. На данный момент атрибут сохранен, но фактически ни на что не влияет.

Добавить пользовательский класс

Последним шагом является добавление пользовательского класса в класс блока. Делаем это с помощью фильтра blocks.getSaveContent.extraProps. Этот фильтр влияет на свойства saveкомпонента блока. Одним из них является prop className, который всегда будет применяться к интерфейсу. Мы просто добавляем наш пользовательский класс после него, если атрибут был true, а затем возвращаем его. Я решил добавить класс ‘ hide-on-mobile‘, но вы можете называть его как хотите.

Этот код говорит сам за себя. В строке #4мы проверяем, существует ли атрибут hideOnMobileи является ли он true. Если это так, мы добавляем к classNameстроке пользовательский класс.

Со всеми тремя вышеуказанными фильтрами теперь мы должны получить настраиваемый класс «скрыть на мобильном устройстве», применяемый к нашему блоку «Обложка» всякий раз, когда этот параметр включен.

Добавьте пользовательские настройки к существующим блокам WordPress Gutenberg

Осталось только добавить немного CSS в таблицу стилей внешнего интерфейса вашей темы. Что-то вроде этого;

.wp-block-cover.hide-on-mobile { display: none; } @media (min-width: 480px) { .wp-block-cover.hide-on-mobile { display: block; } }

Пример 2. Добавление панели «Инспектор» с настраиваемой настройкой цвета фона для блока «Распорка»

Для второго варианта использования мы хотим добавить пользовательские настройки цвета в блок Spacer. По умолчанию блок Spacer не имеет других настроек, кроме высоты. Предположим, мы хотим добавить цвет фона, который раскрашивает всю высоту блока Spacer. Это позволяет пользователю добавлять пустые цветные «полоски» внутри своего контента. В этом случае мы хотим добавить настройки цвета на отдельную панель в Инспекторе, как обычно ожидается для настроек цвета.

Примечание. Обработка цветов немного сложнее, так как нам нужно использовать (другой) компонент более высокого порядка withColors. Потому что нам уже нужно реализовать компонент более высокого порядка в нужном editor.BlockEditнам composeколичестве компонентов. Кроме того, нам нужно добавить два атрибута для каждой настройки цвета. Один будет содержать слаг цветовой палитры, а другой будет содержать шестнадцатеричный код цвета — только если пользователь выбрал собственный цвет (использовал палитру цветов). Это обычное поведение при работе с withColors. У меня есть <a href="https://wordpress.mediadoma.com/ru/kak-dobavit-nastrojki-cveta-v-svoj-sobstvennyj-blok-gutenberga/" title="пост, в котором объясняется добавление настроек цвета и withColorsподробно” >пост, в котором объясняется добавление настроек цвета и withColorsподробно, если вы запутались.

Во-вторых, в этом случае мы столкнемся с проблемой, описанной выше; где мы не можем добавить соответствующий встроенный стиль в редактор. Решение, которое я выбрал в этом случае, состоит в том, чтобы обернуть блок Spacer внутри a divв редакторе и применить к обертке правильные классы и встроенный стиль div. Это делает выбранный цвет видимым в редакторе, когда блок не выбран. Однако при выборе блока WordPress добавляет к блоку свой собственный светло-серый фон, закрывающий наш пользовательский цвет фона. Один CSS для редактора исправит это. Я объясню больше в конце.

Шаги такие же, как в примере выше. Сначала мы ставим наш скрипт в очередь в редакторе на PHP. Затем в Javascript мы фильтруем attributesобъект, editкомпонент Spacer и, наконец, saveкомпонент Spacer.

Добавляем наш скрипт в редактор

Мы подключаем функцию к действию [enqueue_block_editor_assets](https://developer.wordpress.org/reference/hooks/enqueue_block_editor_assets/). Внутри нашей функции мы помещаем скрипт в очередь, как обычно делаем это в wp_enqueue_scriptsхуке.

add_action('enqueue_block_editor_assets', function() { wp_enqueue_script('awp-gutenberg-filters', get_template_directory_uri(). '/assets/js/gutenberg-filters.js', ['wp-edit-post']); });

Не забудьте настроить путь к вашему скрипту. Мне нравится добавлять ‘ wp-edit-post‘ в качестве зависимости к сценарию, чтобы он загружался достаточно поздно.

Это весь PHP, который нам нужно сделать. Остальное написано в нашем файле Javascript.

Добавить пользовательские атрибуты

Как и в примере выше, мы добавляем фильтр blocks.registerBlockType, чтобы добавить дополнительные элементы объекта к attributesобъекту блока.

При работе с withColorsнам нужно добавить два атрибута для каждого цвета. Имя нашего атрибута цвета фона backgroundColor, что означает, что второй атрибут должен быть назван customBackgroundColor. Все это объясняется в моем посте об управлении настройками цвета в Гутенберге. Оба должны быть строкового типа и применяться только к блокам типа Spacer.

function addSpacerAttributes(settings, name) { if (typeof settings.attributes !== 'undefined') { if (name == 'core/spacer') { settings.attributes = Object.assign(settings.attributes, { backgroundColor: { type: 'string', }, customBackgroundColor: { type: 'string' } }); } } return settings; }   wp.hooks.addFilter( 'blocks.registerBlockType', 'awp/spacer-background-attribute', addSpacerAttributes );

Добавить панель ColorSettings в Инспектор

Второй шаг — добавление панели настроек цвета в Инспектор для блока Spacer путем фильтрации editor.BlockEdit.

Нам нужно использовать compose, чтобы объединить компонент более высокого порядка, возвращаемый этим фильтром, и withColors. Другими словами, мы просто оборачиваем возвращаемый компонент в withColors. В качестве параметра withColorsмы предоставляем наш атрибут backgroundColor.

Внутри обернутого компонента мы всегда возвращаемся BlockEdit(строка #9и #39блоки Spacer). Для блока типа Spacer мы также подключаемся InspectorControls, чтобы добавить PanelColorSettingsдля выбора цвета. Это стандартная процедура добавления настроек цвета.

В строке #17 - 34мы вручную генерируем нужный класс и/или встроенный стиль. Затем в строке #38мы добавляем обертку div BlockEditс этими классами и встроенными стилями.

Результатом стала новая панель настроек цвета в Inspector для блоков Spacer, полностью функциональная.

Добавьте пользовательские настройки к существующим блокам WordPress Gutenberg

Выбор цвета палитры или пользовательского цвета действительно будет затронут в обертке div внутри редактора. Но вы можете увидеть это только тогда, когда отмените выбор блока Spacer!

Добавьте пользовательские настройки к существующим блокам WordPress Gutenberg

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

Добавьте пользовательский класс и встроенный стиль для сохранения

Наконец, нам нужно отфильтровать blocks.getSaveContent.extraPropsи применить необходимый класс и/или встроенный стиль для внешнего интерфейса. Опять же, это очень похоже на то, что мы сделали в примере 1 выше. Если был выбран цвет палитры, нам нужно добавить имя класса, соответствующее стандартам WordPress для настройки цвета (« has-<PALETTESLUG>-background-color«). Если был выбран пользовательский цвет, нам нужно добавить встроенный стиль с шестнадцатеричным цветом.

Примечание. Если вам нужно много обрабатывать имена классов, я рекомендую импортировать classnamesбиблиотеку. Это широко используется в Гутенберге, поскольку значительно упрощает установку правильных имен классов. Код ниже предполагает, что вы этого не сделали, и составляет имя класса вручную.

function applySpacerBackground(props, blockType, attributes) { if (blockType.name == 'core/spacer') { const { backgroundColor, customBackgroundColor } = attributes;   // For improved class name handling, use classnames library. Or do it manually like.. let className = (props.className != undefined)? props.className: ''; if (backgroundColor != undefined) { className += ' has-' + backgroundColor + '-background-color'; } props.className = className; if (customBackgroundColor != undefined) { Object.assign(props, { style: { ...props.style, backgroundColor: customBackgroundColor }}); } } return props; }   wp.hooks.addFilter( 'blocks.getSaveContent.extraProps', 'awp/spacer-apply-class', applySpacerBackground );

С приведенным выше кодом внешний интерфейс теперь будет идеально отображать блоки Spacer с нашим собственным выбором цвета!

Последнее (необязательное) исправление — добавить в редактор немного CSS. Вам нужно будет либо добавить встроенный CSS, либо таблицу стилей редактора. Например, вы можете поставить в очередь таблицу стилей в том же хуке PHP, который мы использовали для постановки в очередь нашего файла Javascript. Я не буду вдаваться в подробности того, как это сделать; но CSS, который вам понадобится, выглядит примерно так, как показано ниже. Все, что он делает, это устанавливает для Spacer background-colorунаследованный цвет (он будет унаследован от нашего обертывающего div), когда блок выбран:

.block-library-spacer__resize-container.is-selected { background-color: inherit; }

PS: Имейте в виду, что это может измениться в будущем. Гутенберг все еще сильно развивается.

Вывод

В этом посте мы узнали о двух методах реализации пользовательских настроек в существующих блоках WordPress Gutenberg. Это вполне возможно для простых настроек, которые, возможно, требуют только класса или встроенного стиля. Мы рассмотрели предостережения, которые, я надеюсь, будут исправлены в более поздних версиях Гутенберга!

Источник записи: awhitepixel.com

Этот веб-сайт использует файлы cookie для улучшения вашего опыта. Мы предполагаем, что вы согласны с этим, но вы можете отказаться, если хотите. Принимаю Подробнее