В статье "Создание своего Gutenberg-блока для WordPress на основе wordpress-create-block" мы рассматривали, как создать плагин, который будет давать возможность добавить секцию типа ЧаВо (FAQ) на сайт под управлением WordPress с помощью специального Gutenberg-блока.
Здесь хотелось бы расширить этот плагин добавлением настроек в боковой панели для возможности управления цветом и выравниванием заголовка. Основываться будем на файлах с репозитория на Github.
Управление настройками блока в основной области
Итак, настройки блока могут быть видны при редактировании текста (например, жирный или курсив). Для этого используется панель инструментов, которую мы уже видели. Для настройки кнопок в ней в редакторе Гутенберг существует компонент BlockControls. Ниже на скриншоте вы видите стандартный набор настроек для абзаца.
Что касается этих настроек, их имеет смысл добавлять для RichText. В качестве разрешенных форматов к этому компоненту можно добавить такие опции:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<RichText tagName="h2" value={heading} onChange={(newVal) => setAttributes({ heading: newVal })} placeholder="Title for Accordion Section" allowedFormats={ [ 'core/bold', 'core/italic', 'core/text-color', 'core/subscript', 'core/superscript', 'core/strikethrough', 'core/link', ] } /> |
Из всего перечисленного у нас уже есть 'core/bold' и 'core/italic'. Можем еще добавить 'core/text-color' в allowedFormats для возможности цветового выделения, а вот с помощью компонента BlockControls добавим возможность выравнивания:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<div {...blockProps}> <BlockControls> <AlignmentToolbar value={alignment} onChange={(newVal) => setAttributes({ alignment: newVal })} /> </BlockControls> <RichText tagName='h2' allowedFormats={['core/bold', 'core/italic', 'core/text-color']} value={heading} onChange={(newVal) => setAttributes({ heading: newVal })} placeholder="Title for Accordion Section" style={{ textAlign: alignment }} /> </div> |
Тут не весь код: не хватает объявления атрибута alignment и импорта компонентов BlockControls и AlignmentToolbar. Полный код вы найдете ниже.
Те опции, которые мы добавили, дадут нам возможность выбрать такие настройки:
Настройки боковой панели
Боковая панель настроек находится справа от вашего основного контента и изменяется при выборе разных блоков. Предназначена она для настроек на уровне блока и обычно отвечает за форматирование внутри выделенного блока. Может быть разделена на настройки и стили.
Чтобы добавить стили в виде цвета и отступов (margin, padding), нужно добавить такой код в блок supports файла block.json:
|
1 2 3 4 5 6 7 8 9 10 11 |
{ . . "supports": { "color": {}, "spacing": { "margin": true, "padding": true } } } |
Все стили будут автоматически применяться для вашего блока при изменении любых значений, но тут нужно учитывать, что block.json описывает стили основного компонента, но никак не вложенного(-ых). Поэтому нам придется воспользоваться настройками, заданными самостоятельно.
Для управления боковой панелью существует специальный компонент InspectorControls, который должен выводится для того элемента, к которому они относятся. Соответственно, настройки должны быть доступны при выделении соответствующего блока (главного или вложенных).
Также для добавления раздела настроек вам понадобится компонент Panel и/или PanelBody , который находится в пакете wp.components(то есть вам нужно импортировать PanelBody из wp.components). Компонент позволяет открыть или свернуть настройки (initialOpen={true} для открытой панели), а также позволяет задать заголовок. Вы также можете определить собственный класс, иконку и прикрепить функцию события к триггеру открытия-закрытия.
Для размещения в PanelBody вы можете использовать такие компоненты:
- ToggleControl
- CheckboxControl
- SelectControl
- RadioControl
- ColorPicker
-
ColorPalette и др.
Вы найдете больше компонентов в wp.components репозитории Github.
Цветовая палитра
Поскольку в этой статье мы размещаем прежде всего цветовые настройки, такой код позволит нам вывести цветовую палитру (ColorPalette) для управления цветом текста и фона для нашего аккордеона.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
import { __ } from '@wordpress/i18n'; import { PanelBody} from '@wordpress/components'; import { InnerBlocks, useBlockProps, RichText, BlockControls, AlignmentToolbar, InspectorControls, ColorPalette } from '@wordpress/block-editor'; import './editor.scss'; export default function Edit({ attributes, setAttributes }) { const { heading, alignment, titleTextColor, contentTextColor, titleBgColor, contentBgColor, } = attributes; const accordionStyleVars = { "--tempo-accordion-title-bgcolor": titleBgColor, "--tempo-accordion-title-color": titleTextColor, "--tempo-accordion-font-color": contentTextColor, "--tempo-accordion-panel-background-color": contentBgColor }; const blockProps = useBlockProps({ style: accordionStyleVars }); return ( <div {...blockProps}> <BlockControls> <AlignmentToolbar value={alignment} onChange={(newVal) => setAttributes({ alignment: newVal })} /> </BlockControls> <RichText tagName='h2' allowedFormats={['core/bold', 'core/italic', 'core/text-color']} value={heading} onChange={(newVal) => setAttributes({ heading: newVal })} placeholder="Title for Accordion Section" style={{ textAlign: alignment }} /> <InspectorControls> <PanelBody title={__('Accordion Block Settings', 'accordion-block')} initialOpen={true} > <fieldset> <legend className="blocks-base-control__label"> { __( 'Content Text color', 'accordion-block' ) } </legend> <ColorPalette value={ contentTextColor } onChange={ ( hexColor ) => setAttributes( { contentTextColor: hexColor } ) } /> </fieldset> <fieldset> <legend className="blocks-base-control__label"> { __( 'Content Background color', 'accordion-block' ) } </legend> <ColorPalette value={ contentBgColor } onChange={ ( hexColor ) => setAttributes( { contentBgColor: hexColor } )} /> </fieldset> </PanelBody> </InspectorControls> <InnerBlocks allowedBlocks={['tempo/panel']} template={[ ['tempo/panel', { title: __("Accordion Item Title 1", 'accordion-block') }], ['tempo/panel', { title: __("Accordion Item Title 2", 'accordion-block') }] ]} /> </div> ); } |
Код для save.js вы найдете ниже.
Такой код даст нам настройки вида
Цвета #222222 и transparent заданы в файле index.js или в block.json в качестве дефолтных.
Учтите, что вам нужно сначала обязательно импортировать используемые компоненты из 2-х пакетов:
|
1 2 |
import { PanelBody} from '@wordpress/components'; import { InspectorControls, ColorPalette } from '@wordpress/block-editor'; |
Ошибка при импорте компонента
Поскольку вы не всегда можете знать, какой пакет содержит какие компоненты, при разработке блока для редактора Гутенберг вы можете увидеть ошибку в консоли типа Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.[missing argument].
Эта ошибка может возникнуть, если вы попытаетесь импортировать несуществующий компонент. Вам нужно посмотреть в репозитории компонентов, из какого пакета берется нужный вам и импортировать его правильно. Например, так:
|
1 2 3 |
import { PanelBody, RangeControl} from '@wordpress/components'; import { InnerBlocks, useBlockProps, RichText, InspectorControls, ColorPalette, PanelColorSettings, ContrastChecker } from '@wordpress/block-editor'; |
Панель цветовых настроек
Вместо таких панелей, которые занимают довольно много места, мы можем вывести компонент PanelColorSettings, который будет компактней за счет того, что изначально цветовая палитра спрятана, но при этом вы видите цвет текста и фона блока.
В index.js нам нужно добавить атрибут alignment для BlockControls, о котором речь шла выше + описать атрибуты titleTextColor, contentTextColor, titleBgColor и contentBgColor, которые мы уже частично использовали в компоненте ColorPalette для возможности задать цвет текста и фона отдельно для заголовка и основного текста.
Код в файле index.js:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import { registerBlockType } from '@wordpress/blocks'; registerBlockType(metadata.name, { attributes: { heading: { type: 'string', source: 'html', selector: 'h2', }, alignment: { type: 'string', }, titleTextColor: { type: "string", default: '#222222' }, contentTextColor: { type: "string", default: '#222222' }, titleBgColor: { type: "string", default: 'transparent' }, contentBgColor: { type: "string", default: 'transparent' }, }, edit: Edit, save, }); |
Поскольку изначально мы использовали для блока стили, основанные на CSS-переменных, будем использовать их для того, чтобы изменить цвета всего блока. Все переменные были объявлены для :root. Однако, если мы перенесем их значение на уровень стиля блока, то это наверняка переопределит цвета по умолчанию. Поэтому нам нужно встроить инлайн-стили в наших файлах edit.js и save.js для основного компонента.
Код в файле edit.js:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
import { __ } from '@wordpress/i18n'; import { InnerBlocks, useBlockProps, RichText, BlockControls, AlignmentToolbar, InspectorControls, PanelColorSettings, ContrastChecker } from '@wordpress/block-editor'; import './editor.scss'; export default function Edit({ attributes, setAttributes }) { const { heading, alignment, titleTextColor, contentTextColor, titleBgColor, contentBgColor, } = attributes; const accordionStyleVars = { "--tempo-accordion-title-bgcolor": titleBgColor, "--tempo-accordion-title-color": titleTextColor, "--tempo-accordion-font-color": contentTextColor, "--tempo-accordion-panel-background-color": contentBgColor }; const blockProps = useBlockProps({ style: accordionStyleVars }); return ( <div {...blockProps}> <BlockControls> <AlignmentToolbar value={alignment} onChange={(newVal) => setAttributes({ alignment: newVal })} /> </BlockControls> <RichText tagName='h2' allowedFormats={['core/bold', 'core/italic', 'core/text-color']} value={heading} onChange={(newVal) => setAttributes({ heading: newVal })} placeholder="Title for Accordion Section" style={{ textAlign: alignment }} /> <InspectorControls> <PanelColorSettings title={__('Panel Title Color Settings', 'accordion-block')} icon="art" initialOpen={false} colorSettings={[ { value: titleTextColor, onChange: (hexColor) => setAttributes({ titleTextColor: hexColor }), label: __('Title Font Color', 'accordion-block'), }, { value: titleBgColor, onChange: (hexColor) => setAttributes({ titleBgColor: hexColor }), label: __('Title Background Color', 'accordion-block'), } ]}> <ContrastChecker isLargeText="false" textColor={titleTextColor} backgroundColor={titleBgColor} /> </PanelColorSettings> <PanelColorSettings title={__('Panel Content Color Settings', 'accordion-block')} icon="art" initialOpen={false} colorSettings={[ { value: contentTextColor, onChange: (hexColor) => setAttributes({ contentTextColor: hexColor }), label: __('Content Font Color', 'accordion-block'), }, { value: contentBgColor, onChange: (hexColor) => setAttributes({ contentBgColor: hexColor }), label: __('Content Background Color', 'accordion-block'), } ]}> <ContrastChecker isLargeText="false" textColor={contentTextColor} backgroundColor={contentBgColor} /> </PanelColorSettings> </InspectorControls> <InnerBlocks allowedBlocks={['tempo/panel']} template={[ ['tempo/panel', { title: __("Accordion Item Title 1", 'accordion-block') }], ['tempo/panel', { title: __("Accordion Item Title 2", 'accordion-block') }] ]} /> </div> ); } |
Визуально в админке WordPress это выглядит так:
Код в файле save.js:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import { RichText, InnerBlocks, useBlockProps } from '@wordpress/block-editor'; export default function save({ attributes }) { const { heading, alignment, titleTextColor, contentTextColor, titleBgColor, contentBgColor } = attributes; const accordionStyleVars = { "--tempo-accordion-title-bgcolor": titleBgColor, "--tempo-accordion-title-color": titleTextColor, "--tempo-accordion-font-color": contentTextColor, "--tempo-accordion-panel-background-color": contentBgColor }; const blockProps = useBlockProps.save({ style: accordionStyleVars }); return ( <div {...blockProps}> {heading?.trim().length > 0 && (<RichText.Content tagName="h2" value={heading} style={ { textAlign: alignment } } />)} <InnerBlocks.Content /> </div> ) }; |
После сохранения блока на сайте мы увидим такой аккордеон:
Файлы с настройками вы можете найти на Github.
В нашем плагине мы не передаем настройки блока от родительского блока к дочерним потому, что используем CSS-переменные для изменения цвета. Однако вам может понадобится это сделать в том случае, если вы меняете вид блока в зависимости от какой-то из настроек. Пример такой передачи данных вы найдете в статье Как передавать данные между блоками Gutenberg с помощью контекста блока.





