Adicionar controles à barra lateral do bloco principal e de terceiros com filtros e componentes de ordem superior
Em nosso último guia, analisamos a adição InspectorControlsde nossos blocos personalizados para permitir o uso de controles na barra lateral do bloco. Neste guia, vamos nos basear nisso e adicionar um controle de alternância à barra lateral do bloco de todos os nossos blocos, incluindo qualquer bloco principal e de terceiros que estivermos usando.
Neste guia, vamos criar a funcionalidade ‘draft block’ apresentada no meu plugin Wholesome Publishing.
Pré-requisitos
- Ter seguido o guia Criando um Plugin para o Editor de Blocos do WordPress (Gutenberg)
- Seguiu o guia Adicionar uma barra lateral ao seu bloco WordPress personalizado com InspectorControls
Preparando-se para este guia
Se você seguiu o guia Adicionar uma barra lateral, ótimo. Mas agora vou ter que pedir que você desfaça as alterações feitas na etapa 4 desse guia (o Draft Block Toggle), porque vamos extrapolar essa funcionalidade e aplicá-la a todos os nossos blocos.
Se você não seguiu esse guia, certifique-se de segui-lo até a etapa 4 primeiro, pois este guia segue diretamente daquele.
Criar componentes de ordem superior
Componentes de ordem superior (HoC) são usados no React para envolver um componente existente e passar funcionalidade ou props para esse componente. Eles são chamados de HoCs porque são inseridos no DOM antes do componente existente, ou você poderia dizer em uma ‘Ordem Superior’.
Vamos criar dois novos HoCs, então crie uma nova pasta no seu plugin chamada componentse crie os dois arquivos a seguir:
/components/withInspectorControls.js/components/withIsBlockDraft.js
withInspectorControls
Abra /components/withInspectorControls.jse adicione o seguinte código:
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' );
Você pode reconhecer esse código na etapa 4 do Guia da barra lateral. É praticamente o mesmo código, exceto que o envolvemos em createHigherOrderComponent.
O createHigherOrderComponentque nos permite acessar BlockEditesta é a função de edição original do bloco que este componente irá envolver. Descobriremos como isso é transmitido quando criarmos os filtros em breve.
withIsBlockDraft
Abra /components/withIsBlockDraft.jse cole o seguinte código:
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' );
Isso createHigherOrderComponentnos permite acessar o BlockListBlockque nos permite passar atributos para o wrapper do bloco do editor. Estamos usando-o aqui para definir uma classe ‘draft-block’ para o wrapper se a alternância Draft Block foi definida. Isso recria o que adicionamos anteriormente ao método de edição na etapa 4 do Guia da barra lateral.
Novamente, precisamos configurar um filtro para BlockListBlockque seja passado para este controle.
Configure os filtros
No topo do /src/index.jsarquivo adicione o seguinte:
import { addFilter } from '@wordpress/hooks';
import withIsBlockDraft from './components/withIsBlockDraft';
import withInspectorControls from './components/withInspectorControls';
Realmente devemos pensar em alterar a estrutura do nosso plugin para que o código que registra o bloco seja importado de outro arquivo, mas por simplicidade usaremos o mesmo arquivo.
Filtre os atributos
No mesmo arquivo adicione o seguinte código:
addFilter(
'blocks.registerBlockType',
'wholesome-plugin/block-draft-attributes', (settings) => {
const { attributes } = settings;
return {
...settings,
attributes: {
...attributes,
isBlockDraft: {
default: false,
type: 'boolean',
},
},
};
}
);
Este filtro adiciona atributos adicionais a todos os blocos na compilação. Em teoria, poderíamos filtrar isso apenas para determinados blocos, mas não o faremos para o nosso exemplo.
Se quiséssemos limitar esse filtro a determinados blocos, poderíamos fazer assim:
const { attributes, name } = settings;
if ('core/paragraph' !== name) {
return;
}
Filtre o InspectorControls
Adicione o seguinte código ao /src/index.jsarquivo:
addFilter(
'editor.BlockEdit',
'wholesome-plugin/block-draft-inspector',
withInspectorControls,
);
Aqui filtramos BlockEditpara que passe isso para o nosso HoC que criamos anteriormente.
Se quiséssemos limitar esse filtro a determinados blocos, faríamos o seguinte dentro do HoC :
if ('core/paragraph' === props.name) {
return <BlockEdit { ...props } />
}
Filtre o BlockListBlock
Finalmente vamos adicionar o filtro para o nosso BlockListBlock:
addFilter(
'editor.BlockListBlock',
'wholesome-plugin/block-draft-class',
withIsBlockDraft
);
Novamente, se você quiser restringir este bloco, você pode fazer isso dentro do HoC.
Adicione o PHP e SCSS
Adicione o seguinte para /editor.scssdeixar nosso banner de rascunho bonito (isso pode ser feito muito melhor, mas este é apenas um exemplo).
.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;
}
}
}
Adicione o seguinte ao arquivo raiz do plugin (no nosso caso 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 );
Isso interromperá a saída dos blocos de rascunho no frontend.
Vendo isso em ação
Lembre-se de compilar npm starte agora podemos definir qualquer tipo de bloco para um bloco de rascunho:
Configurando e desarmando blocos de rascunho
- Dê uma olhada na criação de blocos filho aninhados com o
InnerBlockscomponente - Dê uma olhada no uso de meta campos post em blocos Gutenberg
- Experimente adicionar controles à barra lateral do post