Добавьте элементы управления на боковую панель основного и стороннего блока с фильтрами и компонентами более высокого порядка
В нашем последнем руководстве мы рассмотрели добавление InspectorControlsк нашим пользовательским блокам, чтобы мы могли использовать элементы управления на боковой панели блока. В этом руководстве мы собираемся опираться на это и добавим переключатель на боковую панель всех наших блоков, включая любые основные и сторонние блоки, которые мы используем.
В этом руководстве мы создадим функцию «черновик блока», которая представлена в моем плагине Wholesome Publishing.
Предпосылки
- Следовали руководству по созданию плагина для редактора блоков WordPress (Gutenberg).
- Следовали руководству по добавлению боковой панели в пользовательский блок WordPress с помощью InspectorControls .
Подготовка к этому руководству
Если вы следовали руководству по добавлению боковой панели, отлично. Но теперь мне придется попросить вас отменить изменения, сделанные вами на шаге 4 этого руководства (Переключение чернового блока), потому что мы собираемся экстраполировать эту функциональность и применить ее ко всем нашим блокам.
Если вы не следовали этому руководству, убедитесь, что вы выполнили его сначала до шага 4, так как это руководство следует непосредственно из него.
Создайте компоненты более высокого порядка
Компоненты высшего порядка (HoC) используются в React, чтобы обернуть существующий компонент и либо передать функциональность, либо свойства этому компоненту. Их называют HoC, потому что они вставляются в DOM перед существующим компонентом или, можно сказать, в «высшем порядке».
Мы собираемся создать два новых HoC, поэтому создайте новую папку в вашем плагине componentsи создайте следующие два файла:
/components/withInspectorControls.js/components/withIsBlockDraft.js
withInspectorControls
Откройте /components/withInspectorControls.jsи добавьте следующий код:
import { InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ToggleControl } from '@wordpress/components';
import { createHigherOrderComponent } from '@wordpress/compose';
import { Fragment } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
export default createHigherOrderComponent( (BlockEdit) => {
return (props) => {
const {
attributes: {
isBlockDraft,
},
setAttributes,
} = props;
return (<Fragment>
<BlockEdit { ...props } />
<InspectorControls>
<PanelBody
title={ __( 'Block Display Settings', 'wholesome-plugin') }
icon="visibility"
initialOpen={ false }
>
<ToggleControl
label={ __( 'Set Block as Draft', 'wholesome-plugin') }
checked={ isBlockDraft }
onChange={ (isBlockDraft) => setAttributes( { isBlockDraft }) }
help={ __( 'If the block is set to draft it will not show on the front end.',
'wholesome-plugin') }
/>
</PanelBody>
</InspectorControls>
</Fragment>
);
};
}, 'withInspectorControls' );
Вы можете узнать этот код из шага 4 Руководства по боковой панели. Это почти тот же код, за исключением того, что мы обернули его в createHigherOrderComponent.
Позволяет createHigherOrderComponentнам получить доступ BlockEditк исходной функции редактирования блока, который этот компонент будет обертывать. Мы узнаем, как это передается, когда вскоре создадим фильтры.
сИсБлокДрафт
Откройте /components/withIsBlockDraft.jsи вставьте следующий код:
import { createHigherOrderComponent } from '@wordpress/compose';
export default createHigherOrderComponent( (BlockListBlock) => {
return (props) => {
const { attributes } = props;
const { isBlockDraft } = attributes;
return <BlockListBlock { ...props } className={ isBlockDraft? 'draft-block': '' } />;
};
}, 'withIsBlockDraft' );
Это createHigherOrderComponentпозволяет нам получить доступ BlockListBlock, который позволяет нам передавать атрибуты в оболочку блока редактора. Мы используем его здесь, чтобы установить класс ‘draft-block’ для оболочки, если был установлен переключатель Draft Block. Это воссоздает то, что мы ранее добавили в метод редактирования на шаге 4 Руководства по боковой панели.
Опять же, нам нужно настроить фильтр для BlockListBlockпередачи в этот элемент управления.
Настройте фильтры
В начало /src/index.jsфайла добавьте следующее:
import { addFilter } from '@wordpress/hooks';
import withIsBlockDraft from './components/withIsBlockDraft';
import withInspectorControls from './components/withInspectorControls';
Нам действительно следует подумать об изменении структуры нашего плагина, чтобы код, регистрирующий блок, импортировался из другого файла, но для простоты мы будем использовать тот же файл.
Фильтровать атрибуты
В этот же файл добавьте следующий код:
addFilter(
'blocks.registerBlockType',
'wholesome-plugin/block-draft-attributes', (settings) => {
const { attributes } = settings;
return {
...settings,
attributes: {
...attributes,
isBlockDraft: {
default: false,
type: 'boolean',
},
},
};
}
);
Этот фильтр добавляет дополнительные атрибуты ко всем блокам в сборке. Теоретически мы могли бы отфильтровать это только для определенных блоков, но мы не собираемся этого делать для нашего примера.
Если бы мы хотели ограничить этот фильтр определенными блоками, мы могли бы сделать это так:
const { attributes, name } = settings;
if ('core/paragraph' !== name) {
return;
}
Фильтровать InspectorControls
Добавьте в /src/index.jsфайл следующий код:
addFilter(
'editor.BlockEdit',
'wholesome-plugin/block-draft-inspector',
withInspectorControls,
);
Здесь мы фильтруем BlockEdit, чтобы он передал это нашему HoC, который мы создали ранее.
Если бы мы хотели ограничить этот фильтр определенными блоками, мы бы сделали в HoC следующее :
if ('core/paragraph' === props.name) {
return <BlockEdit { ...props } />
}
Отфильтровать BlockListBlock
Наконец, давайте добавим фильтр для нашего BlockListBlock:
addFilter(
'editor.BlockListBlock',
'wholesome-plugin/block-draft-class',
withIsBlockDraft
);
Опять же, если вы хотите ограничить этот блок, вы можете сделать это внутри HoC.
Добавьте PHP и SCSS
Добавьте следующее, /editor.scssчтобы наш черновой баннер выглядел красиво (это можно сделать намного лучше, но это всего лишь пример).
.editor-styles-wrapper {
.draft-block {
border-bottom: 1px dotted #cfcfcf;
border-left: 1px solid #cfcfcf;
border-right: 1px solid #cfcfcf;
margin-top: 3em;
&::before {
background: #cfcfcf;
background-image: linear-gradient(45deg, #efefef 8.33%, #cfcfcf 8.33%, #cfcfcf 50%, #efefef 50%, #efefef 58.33%, #cfcfcf 58.33%, #cfcfcf 100%);
background-size: 8.49px 8.49px;
border-left: 1px solid #cfcfcf;
border-right: 1px solid #cfcfcf;
border-top: 1px solid #cfcfcf;
color: black;
content: 'Draft Block';
display: block;
font-family: monospace;
font-size: 1rem;
left: 0;
padding-left: 5px;
position: absolute;
top: -27px;
width: 100%;
}
opacity: .4;
&.is-selected {
opacity: .8;
}
}
}
Добавьте следующее в корневой файл плагина (в нашем случае wholesome-plugin.php).
function wholesomecode_wholesome_plugin_remove_blocks_in_draft( $pre_render, $block) {
if (is_admin()) {
return $pre_render;
}
if (isset( $block['attrs']) &&
isset( $block['attrs']['isBlockDraft']) &&
$block['attrs']['isBlockDraft']) {
return false;
}
return $pre_render;
}
add_filter( 'pre_render_block', 'wholesomecode_wholesome_plugin_remove_blocks_in_draft', 0, 2 );
Это остановит вывод черновых блоков на интерфейс.
Видеть это в действии
Не забудьте скомпилировать с помощью npm start, и теперь мы можем установить любой тип блока в черновой блок:
Установка и снятие черновых блоков
- Посмотрите на создание вложенных дочерних блоков с
InnerBlocksкомпонентом - Взгляните на использование метаполей сообщений в блоках Гутенберга.
- Попробуйте добавить элементы управления на боковую панель поста.