Esse post é o terceiro de uma série de posts sobre o blocos Gutenberg. Nesse tutorial vamos abordar blocos gutenberg trabalhando com atributos em posts customizados. Nos posts anteriores vimos como registrar o nosso bloco customizado e adicionar um estilo ao nosso markup.
Agora vamos entender como os atributos funcionam dentro do WordPress. Caso ainda não viu os posts anteriores você confere aqui:
Atributos
Até o momento, nos posts anteriores, quando registramos o nosso primeiro bloco passamos apenas um paragrafo estático, mas caso queiramos dar a possibilidade para o usuário cadastrar uma informação dinamicamente através do editor como serão os próximos passos? Vimos durante a chamada da função edit podemos receber um objeto com propriedades relacionadas ao nosso bloco e uma dessas informações é a propriedade attributes. Para trabalhar com a edição de conteúdo vamos trabalhar com alguns componentes do WordPress.
Componentes
Os blocos muitas vezes repetem a mesma complexidade, isso nos permite aplicar a reutilização de certos recursos, para simplificar a edição de conteúdo, o core do WordPress tem uma série componentes React que realizam tarefas específicas, mas não se assuste você não precisa aprender React para utilizar esse recursos. Mas meu conselho se você que trabalhar de forma mais produtiva é uma tecnologia que ajuda bastante, mas o foco desse tutorial vamos trabalhar com EcmaScript5, Dentro dos componentes vamos abordar dois componentes:
RichText
Ele irá renderizar para nos um input editável com a possibilidade de inclusa de texto e links. Dentro do componente RichText temos as seguintes propriedades:
- value: espera um valor do tipo string, será o conteúdo armazenado ate o momento, podendo ser texto ou markup valido.
- onChange: esse atributo espera uma função, será o callback responsável quando o valor do atributo sofre uma alteração
- placeholder: O valor do campo quando estiver vazio. isso é válido tanto para o input text ou textarea o valor será o mesmo
- multiline: Se o bloco irá permitir que o usuário cadastre multiplas linhas quando presionar enter, quando desabilitado o cada enter irá criar um novo bloco.
BlockControls
Quando nosso bloco é renderizado dentro do editor, uma barra de ferramentas é exibida com algumas opções relacionadas ao bloco selecionado, por exemplo, caso queiramos exibir opções de alinhamento de texto ao nosso bloco passamos o elemento responsável por alinhamento. O BlockControls espera o seguinte:
- icon: slug do dashicon para ser mostrado na barra de controle
- title: um título será exibido em forma de tooltip para o usuário
- subscript: Um texto opcional para ser exibido adjacente ao ícone da barra de controle
- isActive: um booleano para definir se o barra de controle será selecionada ou não por default.
Para esse tutorial vamos registrar dois blocos, primeiro exemplo(script.js) apenas com um richText component e o segundo bloco fazendo o uso do blockControl e richText(script-controls.js).
script.js
/**
* 1 - Criando primeiro bloco Gutenberg com ES5: parte 03
* - carregando atributos
*/
( function( blocks, element, editor ) {
var el = element.createElement,
RichText = editor.RichText;
//registrando nosso bloco
blocks.registerBlockType( 'fellyph/tutorial-03', {
title: 'Primeiro bloco Gutenberg: Parte 03',
icon: 'smiley',
category: 'layout',
//registrando o tipo de bloco que iremos trabalhar
attributes: {
content: {
type: 'string',
source: 'html',
selector: 'p',
}
},
// função responsável por exibir nosso bloco no editor
edit: function(props) {
var content = props.attributes.content;
// função responsável por acompanhar as mudanças do nosso atributo
function onChangeContent( newContent ) {
props.setAttributes( { content: newContent } );
}
// agora retornamos um elemento RichText ao invés de um parâgrafo
return el(
RichText,
{
tagName: 'p',
className: props.className,
onChange: onChangeContent,
value: content,
}
);
},
save: function(props) {
return el(
RichText.Content , {
tagName: 'p',
className: props.className,
value: props.attributes.content,
}
);
},
});
}(
window.wp.blocks,
window.wp.element,
window.wp.editor
) );
Code language: JavaScript (javascript)
Como podemos ver no código acima, vamos ter mais uma dependência a classe editor do WordPress presente no script wp-editor, nela vamos encontrar os componentes relacionados a edição de conteúdo. Próximo passo adicionamos em uma variável nosso RichText, seguindo nosso código dentro do registerBlockType temos algumas alterações, adicionamos uma nova propriedade attributes ele é responsável pela configuração do nosso atributo. Ela merece um post específico só falando sobre
Mas voltando para o nosso tutorial definimos a configuração do atributo content esse nome pode ser qualquer um, por exemplo, “conteúdo”. Para esse atributo passamos um objeto de configuração como o tipo do dado(type), a fonte que iremos receber do editor(source), valores padrões(default) entre outras informações.
Dentro da função do edit, o nosso elemento RichText definimos os atributos tagName, className, onChange, value. Também criamos uma função onChangeContent ela é necessária por conta de um conceito do React de controle de estado, precisamos implementar um controlled component para isso, um resumo bem grosseiro, precisamos conectar o valor do input com o estado do component.
Index.php
Algumas diferenças na implementação do index.php, são o registro de dois blocos e quando registramos nosso script precisar adicionar a dependência ao ‘wp-editor’.
<?php
/**
* Plugin Name: Gutenberg tutorial
* Plugin URI: https://github.com/fellyph/gutenberg-tutorials
* Description: Este tutorial ensina como criar um bloco gutenberg https://blog.fellyph.com.br/wordpress-2/criando-seu-proprio-bloco-gutenberg/.
* Version: 1.3
* Author: fellyph
*/
defined( 'ABSPATH' ) || exit;
/**
* 1 - Criando nosso primeiro bloco: Parte 03
* 1.1 - Adicionando o recurso de cadastrar atributos
* 1.2 - Adicionando o bloco com block control
*/
function meu_primeiro_bloco_gutenberg_parte_03 () {
if ( ! function_exists( 'register_block_type' ) ) {
// Checamos se temos suporte a função register_block_type antes de tudo.
return;
}
wp_register_script(
'tutorial-03',
plugins_url( 'script.js', __FILE__ ),
array( 'wp-blocks', 'wp-element', 'wp-editor' ),
filemtime( plugin_dir_path( __FILE__ ) . 'script.js' )
);
wp_register_script(
'tutorial-03-alinhamento',
plugins_url( 'script-controls.js', __FILE__ ),
array( 'wp-blocks', 'wp-element', 'wp-editor' ),
filemtime( plugin_dir_path( __FILE__ ) . 'script-controls.js' )
);
wp_register_style(
'style-editor',
plugins_url( 'editor-style.css', __FILE__ ),
array('wp-edit-blocks'),
filemtime( plugin_dir_path( __FILE__ ) . 'editor-style.css' )
);
wp_register_style(
'style-frontend',
plugins_url( 'style.css', __FILE__ ),
filemtime( plugin_dir_path( __FILE__ ) . 'style.css' )
);
register_block_type( 'fellyph/tutorial-03', array(
'style' => 'style-frontend',
'editor_script' => 'tutorial-03',
'editor_style' => 'style-editor'
));
register_block_type( 'fellyph/tutorial-03-alinhamento', array(
'style' => 'style-frontend',
'editor_script' => 'tutorial-03-alinhamento',
'editor_style' => 'style-editor'
));
}
add_action( 'init', 'meu_primeiro_bloco_gutenberg_parte_03' );
Code language: HTML, XML (xml)
Um ponto importante em nosso script, quando registramos um novo id(fellyph/tutorial-03-alinhamento e fellyph/tutorial-03) para nosso bloco precisamos atualizar o nosso seletores CSS:
.wp-block-fellyph-tutorial-03-alinhamento,
.wp-block-fellyph-tutorial-03 {
background: #12c2e9;
border: 3px solid #666;
box-shadow: 0 0 0 #666;
}
.wp-block-fellyph-tutorial-03-alinhamento:hover,
.wp-block-fellyph-tutorial-03:hover {
transform: rotate3d(0, 0, 0, 0);
}
Code language: CSS (css)
script-controls.js
/**
* 1 - Criando primeiro bloco Gutenberg com ES5: parte 03
* - carregando atributos com BlockControls
*/
( function( blocks, element, editor ) {
var el = element.createElement,
RichText = editor.RichText,
AlignmentToolbar = editor.AlignmentToolbar,
BlockControls = editor.BlockControls;
//registrando nosso bloco
blocks.registerBlockType( 'fellyph/tutorial-03-alinhamento', {
title: 'Bloco com controle de alinhamento',
icon: 'welcome-view-site',
category: 'layout',
//registrando os atributos que iremos trabalhar
attributes: {
content: {
type: 'string',
source: 'html',
selector: 'p'
},
alinhamento: {
type: 'string',
default: 'none'
},
},
// unção responsável por exibir nosso bloco no editor
edit: function(props) {
var content = props.attributes.content;
var alinhamento = props.attributes.alinhamento;
// função responsável por acompanhar as mudanças do nosso atributo
function onChangeContent( newContent ) {
props.setAttributes( { content: newContent } );
}
function onChangeAlignment (nextAlign ) {
props.setAttributes( { alinhamento: nextAlign } );
}
// agora retornamos um array por que estamos utilizando dois componentes
return [
el( BlockControls,
{ key: 'controls' },
el( AlignmentToolbar, {
value: alinhamento,
onChange: onChangeAlignment
})
),
el(
RichText,
{
key: 'richtext',
tagName: 'p',
style: { textAlign: alinhamento },
className: props.className,
onChange: onChangeContent,
value: content,
placeholder: 'Insira seu nome aqui'
}
),
];
},
save: function(props) {
return el(
RichText.Content , {
tagName: 'p',
className: props.className,
style: { textAlign: props.attributes.alinhamento },
value: props.attributes.content,
}
);
},
});
}(
window.wp.blocks,
window.wp.element,
window.wp.editor
) );
Code language: JavaScript (javascript)
No código acima temos alguns pontos importantes diferente do primeiro código, em atributos adicionamos um novo valor, “alinhamento” ele será do tipo string e terá um valor padrão ‘none’.
Dentro da função edit adicionamos uma função para acompanhar as mudanças desse componente onChangeAlignment onde atualizamos o valor do atributo referente ao alinhamento.
Agora quando retornamos o nosso bloco utilizamos um array para passar mais de um componente, por que precisamos de um blockControls para passar as configurações necessárias e um RichText para o usuário cadastrar um texto.
Dentro do nosso blockControls podemos também passar uma série de outros componentes relacionados a configurações mas para esse caso vamos utilizar apenas o AlignmentToolbar :

Em seguida conectamos o valor do aligmentToolbar ao nosso RichText, tanto no preview na função edit quando no nosso front-end na função save, definindo o atributo style: { textAlign: alinhamento }.
E esse será o resultado dos dois blocos que criamos aqui:



Conclusão sobre blocos gutenberg trabalhando com atributos
Como podemos ver, gutenberg utiliza o mesmo esquema de atualização de atributos que o react, se quiser conferir a evolução desse projeto o código desse tutorial você irá encontrar no meu git, para cada tutorial estou criando uma branch:
https://github.com/fellyph/Gutenberg-tutorials/tree/tutoriais/gutenberg-03
Qualquer feedback deixe aqui seu comentário e até o próximo tutorial
Referências:
https://wordpress.org/gutenberg/handbook/designers-developers/developers/block-api/block-attributes/
https://wordpress.org/gutenberg/handbook/designers-developers/developers/packages/packages-editor/
Deixe um comentário