Muitas pessoas reclamam sobre os obstáculos para começar a construir blocos e aplicativos Gutenberg. A curva de aprendizado é íngreme, principalmente devido à dificuldade de instalar e configurar o ambiente de desenvolvimento. Além disso, um sólido conhecimento de JavaScript, Node.js, React e Redux são ingredientes indispensáveis para esta receita bastante complexa.

O Manual Oficial do Editor de Blocos do WordPress fornece aos desenvolvedores uma tremenda quantidade de informações, mas você pode se ver perdido naquele mar de detalhes.

E vale a pena mencionar o que Matías Ventura, arquiteto líder do projeto Gutenberg, relatou em sua entrevista com a WP Tavern:

Enquanto há pessoas que podem aprender rapidamente, ainda é uma grande barreira para as pessoas. Eu acho que há várias camadas para isso; a documentação poderia ser uma ordem de magnitude melhor tanto na organização quanto na apresentação. Eu espero que possamos fazer muito mais lá.

Com isso em mente, nós decidimos fornecer um tutorial passo a passo com o objetivo de ajudar nossos leitores a começar com o desenvolvimento de blocos Gutenberg.

Parece interessante? Vamos mergulhar!

Pré-requisitos para o desenvolvimento de blocos Gutenberg

Para este tutorial, as únicas habilidades necessárias serão um bom conhecimento do desenvolvimento de plugins WordPress e pelo menos um entendimento básico de HTML, CSS, JavaScript e React.

Será que este será um projeto ambicioso? Você pode apostar que sim!

Não foi fácil encontrar o compromisso certo entre completude e simplicidade ou decidir quais tópicos incluir e quais deixar de fora.

Esperamos que os leitores intermediários e avançados nos perdoem por não nos aprofundarmos em certos conceitos, tais como React state, Redux store, componentes de alta ordem, e assim por diante. Estes tópicos requerem espaço e atenção adicionais e provavelmente são muito avançados para iniciar o desenvolvimento em bloco (a menos que você seja um desenvolvedor React).

Pela mesma razão, não vamos cobrir alguns dos tópicos mais avançados relacionados ao desenvolvimento de blocos Gutenberg, tais como blocos dinâmicos e meta boxes.

Com o conhecimento que você ganhará ao final deste artigo, você poderá começar a se divertir e ser produtivo imediatamente.

Uma vez que você começar a construir blocos, você estará pronto para melhorar ainda mais suas habilidades e construir blocos Gutenberg ainda mais avançados por conta própria.

Começar com o desenvolvimento de blocos Gutenberg pode ser intimidante no começo... 😵‍💫 Mas sem medo! Este completo guia para iniciantes tem você coberto 🙏Click to Tweet

O que é um bloco Gutenberg?

Desde que foi lançado pela primeira vez em dezembro de 2018, o editor de blocos foi muito melhorado em todos os aspectos: APIs mais poderosas, uma interface de usuário mais avançada, melhor usabilidade, uma tonelada de novos blocos, as primeiras implementações do Full site editing (Edição completa do site), e muito mais.

Em resumo, mesmo que o Gutenberg ainda esteja em um desenvolvimento pesado, ele percorreu um longo caminho – e hoje, o editor de blocos é um candidato de pleno direito como um construtor confiável e funcional de páginas e sites.

Do ponto de vista de um desenvolvedor, Gutenberg é um aplicativo de página única (SPA) baseado em reações que permite aos usuários do WordPress criar, editar e excluir conteúdo no WordPress. Entretanto, isto não deve fazer você pensar em uma versão melhorada do editor de conteúdo tradicional.

Nós queremos deixar isso claro:

No Gutenberg, o conteúdo é dividido em blocos, que são “bricks” que os usuários podem usar para criar artigos e páginas ou sites inteiros.

Mas o que tecnicamente é um bloco?

Nós gostamos da definição do WordPress:

“Bloco” é o termo abstrato usado para descrever unidades de marcação que, compostas juntas, formam o conteúdo ou layout de uma página da web. A idéia combina conceitos do que no WordPress de hoje nós conseguimos com atalhos, HTML personalizado e incorporação da descoberta em uma única API consistente e experiência do usuário.

Títulos, parágrafos, colunas, imagens, galerias e todos os elementos que compõem a interface do editor, desde painéis de barra lateral até controles de barra de ferramentas de bloqueio, são componentes React.

Então, o que são componentes React? W3Schools fornece a seguinte definição:

Os componentes são bits de código independentes e reutilizáveis. Eles servem ao mesmo propósito que as funções JavaScript, mas funcionam isoladamente e retornam o HTML através de uma função render().

Working with Gutenberg blocks in WordPress 5.8.
Trabalhando com blocos Gutenberg no WordPress 5.8.

Enquanto que a experiência de edição fornecida pelo Gutenberg é nova em comparação com o editor WordPress clássico, a maneira como o WordPress armazena suas peças de conteúdo no banco de dados não muda em nada. Isso porque o Gutenberg é um aplicativo que funciona dentro do WordPress, mas não muda a maneira como o CMS funciona em sua essência.

Os artigos (isto inclui artigos, páginas e tipos de artigos personalizados) criados com o Gutenberg ainda são armazenados na tabela wp_posts, exatamente como com o editor clássico.

Mas em um artigo criado com o Gutenberg, você encontrará pedaços adicionais de informação na tabela que representam uma diferença fundamental entre artigos criados através do Editor Clássico vs. Gutenberg. Essas informações se parecem com comentários HTML, e elas têm uma função específica: delimitar blocos:

Um post no blog na visualização do editor de código.
Um artigo no blog na visualização do editor de código.

Os delimitadores de blocos dizem ao WordPress qual bloco deve ser apresentado na tela. Eles também fornecem valores para as propriedades do bloco em um objeto JSON. Esses adereços ditam a forma como o bloco deve ser renderizado na tela:

A blog post stored in the wp_posts table.
Um artigo do blog armazenado na tabela wp_posts.

Configurando seu ambiente de desenvolvimento WordPress

A criação de um ambiente moderno de desenvolvimento JavaScript requer um sólido conhecimento de tecnologias avançadas como Webpack, React e JSX, Babel, ESLint, etc.

Intimidado? Não fique! A comunidade WordPress já chegou ao socorro, fornecendo ferramentas poderosas que permitem evitar um processo de configuração manual bagunçado.

Para manter as coisas simples, não iremos cobrir a transpilação neste artigo (que, no entanto, recomendamos que você se familiarize uma vez que você tenha aprendido as bases do desenvolvimento de blocos). Ao invés disso, vamos introduzir duas ferramentas alternativas que você pode usar para configurar rápidamente e facilmente um ambiente de desenvolvimento moderno em JavaScript em poucos minutos. Cabe a você escolher aquele que você achar mais conveniente para o seu projeto.

A criação de um ambiente de desenvolvimento JavaScript para construir blocos Gutenberg é um processo de três etapas:

  1. Instale o Node.js e npm
  2. Configure o ambiente de desenvolvimento
  3. Configure o plugin do bloco

Vamos começar.

1. Instale Node.js e npm

Antes de instalar seu ambiente de desenvolvimento e registrar seu primeiro bloco, você precisará instalar o Node.js e o gerenciador de pacotes do Node (npm).

.

Você pode instalar o Node.js e npm de várias maneiras diferentes. Mas primeiro, você pode querer verificar se o software já está instalado em sua máquina.

Para fazer isso, abra o terminal e execute o seguinte comando:

node -v

Se o resultado for command not found, então o Node.js não está instalado em seu computador, e você pode prosseguir com a instalação.

Para este artigo, nós escolhemos a opção de instalação mais fácil, que é o Node Installer. Tudo o que você precisa fazer é baixar a versão correspondente do seu sistema operacional e iniciar o assistente de instalação:

Node.js Downloads page.
Página de downloads do Node.js

Uma vez instalado o Node.js, execute novamente o comando node -v em seu terminal. Você também pode executar o comando npm -v para confirmar que você tem o pacote npm disponível. Agora você está equipado com as seguintes ferramentas:

O próximo passo é a instalação do ambiente de desenvolvimento.

2. Configure o ambiente de desenvolvimento

Assim que você tiver as últimas versões do Node.js e npm em sua máquina local, você precisará de um ambiente de desenvolvimento para WordPress.

Você pode usar um ambiente de desenvolvimento local como o DevKinsta ou usar a ferramenta oficial do WordPress. Vamos dar uma olhada em ambas as opções.

Opção 1: Ambiente de desenvolvimento Local (DevKinsta)

Com apenas alguns cliques, você pode instalar o WordPress localmente usando DevKinsta, nossa moderna ferramenta de desenvolvimento WordPress local. Ou você pode optar por uma ferramenta de desenvolvimento local diferente, como MAMP ou XAMPP:

Create a new WordPress website in DevKinsta.
Crie um novo site WordPress no DevKinsta

Opção 2: wp-env

Você também pode optar pela ferramentawp-env oficial , que fornece um ambiente WordPress dev local que você pode lançar diretamente da linha de comando. Noah Alen o define da seguinte forma:

Os ambientes locais de WordPress agora são tão simples quanto rodar um único comando. wp-env é uma ferramenta de configuração zero para ambientes locais de WordPress sem dor de cabeça. Ele fornece decisões sobre opções para que os usuários possam rapidamente rodar o WordPress sem perda de tempo. De fato, o objetivo é tornar estes ambientes facilmente acessíveis a todos – seja você um desenvolvedor, designer, gerente ou qualquer outra pessoa.

Se você decidir tentar, a instalação do wp-env requer um esforço mínimo. Basta seguir estes passos:

Passo 1: Confirme a instalação do Docker e do Node.js

Para atender aos requisitos técnicos, você precisará primeiro ter o Docker e o Node.js instalados no seu computador. Isso porque wp-env cria uma instância do Docker rodando um site WordPress. Quaisquer mudanças feitas no código são imediatamente refletidas na instância do WordPress.

Passo 2: Instale @wordpress/env a partir da Linha de Comando

Com o Docker e o Node.js rodando em seu computador, você pode seguir em frente e instalar o ambiente de desenvolvimento do WordPress. Você pode instalar wp-env tanto global quanto localmente. Para fazê-lo globalmente, você precisará executar o seguinte comando de dentro do diretório de plugins (mais sobre isso na caixa de aviso “Importante” abaixo):

npm install -g @wordpress/env

Vamos analisar isso:

.

Para confirmar que o wp-env foi instalado com sucesso, execute o seguinte comando:

wp-env --version

Você deve ver a atual versão wp-env, o que significa que agora você pode iniciar o ambiente usando o seguinte comando da pasta do seu plugin:

wp-env start

Você pode acessar o painel de controle do WordPress usando o seguinte endereço:

As credenciais padrão são as seguintes:

Configure o seu plugin de bloco

Agora você precisa de um plugin de bloco de partida para construir. Mas ao invés de criar manualmente um plugin de bloco de desenvolvimento com todos os arquivos e pastas necessários, você pode simplesmente executar uma ferramenta de desenvolvimento fornecendo todos os arquivos e configurações que você precisa para começar com o desenvolvimento de blocos.

Novamente, você tem um par de opções para escolher. Vamos dar uma olhada em cada uma delas.

Opção 1: Configurando um plugin de bloco com @wordpress/create-block

@wordpress/create-block é a ferramenta oficial de configuração zero para a criação de blocos Gutenberg:

Create Block é uma forma oficialmente suportada de criar blocos para registrar um bloco para um plugin WordPress. Ele oferece uma configuração de construção moderna sem nenhuma configuração. Ele gera código PHP, JS, CSS e tudo mais que você precisa para iniciar o projeto.

Ele é inspirado em grande parte pela create-react-app. Parabéns ao @gaearon, toda a equipe do Facebook e a comunidade React.

Uma vez que seu ambiente local esteja pronto e funcionando, você pode configurar um bloco inicial simplesmente executando o comando npx @wordpress/create-block, e ele fornecerá todos os arquivos e pastas que você precisa para criar o plugin scaffolding e registrar um novo bloco.

Vamos fazer um teste para ver como funciona.

Da sua ferramenta de Linha de Comando, navegue para o diretório /wp-content/plugins/ e execute o seguinte comando:

npx @wordpress/create-block my-first-block

Quando for solicitado para confirmar, digite y para prosseguir:

Creating a block with @wordpress/create-block.
Criando um bloco com @wordpress/create-block

O processo leva poucos momentos. Quando estiver completo, você deve obter a seguinte resposta:

The block plugin has been created.
O plugin de bloco foi criado

E é isso aí!

Agora lance seu ambiente de desenvolvimento WordPress e vá para a tela Plugins no painel do WordPress. Um novo plugin chamado “Meu Primeiro Bloco” deveria ter sido adicionado à sua lista de plugins:

The block plugin has been successfully installed.
O plugin de bloco foi instalado com sucesso

Ative o plugin se necessário, crie um novo artigo no blog, desça o inseridor de blocos até a seção Widgets e selecione seu novo bloco:

An example block created with @wordpress/create-block.
Um bloco de exemplo criado com @wordpress/create-block

Agora volte para o terminal e mude o diretório atual para o meu primeiro bloco:

cd my-first-block

Então execute o seguinte comando:

npm start

Isto permite que você execute o plugin no modo de desenvolvimento. Para criar o código de produção, você deve usar o seguinte comando:

npm run build

Opção 2: Configurando um plugin de bloco com create-guten-block

create-guten-block é uma ferramenta de desenvolvimento de terceiros para a construção de blocos Gutenberg:

create-guten-block é um dev-toolkit de configuração zero (#0CJS) para desenvolver blocos Gutenberg do WordPress em questão de minutos sem configurar React, webpack, ES6/7/8/Next, ESLint, Babel, etc.

Assim como a ferramenta oficial create-block, create-guten-block é baseado em create-react-app e pode ajudar você a gerar seu primeiro plugin de bloco sem complicações.

O kit de ferramentas fornece tudo o que você precisa para criar um plugin WordPress moderno, incluindo o seguinte:

  • React, JSX e ES6 suporte de sintaxe.
  • webpack processo de desenvolvimento/produção por trás do cenário.
  • Extras de linguagem além do ES6 como o operador de propagação de objetos.
  • CSS auto-prefixado, então você não precisa de -webkit ou outros prefixos.
  • Um script de construção para agrupar JS, CSS e imagens para produção com source-maps.
  • Atualizações sem complicação para as ferramentas acima com uma única dependência cgb-scripts.

Observe a seguinte advertência:

A contrapartida é que estas ferramentas são pré-configuradas para funcionar de uma forma específica. Se o seu projeto precisa de mais personalização, você pode “ejetar” e personalizá-lo, mas então você precisará manter esta configuração.

Uma vez que você tenha um site WordPress local em mãos, abra sua ferramenta de Linha de Comando, navegue para a pasta /wp-content/plugins da sua instalação, e execute o seguinte comando:

npx create-guten-block my-first-block

Você terá que esperar um ou dois minutos enquanto a estrutura do projeto é criada e as dependências são baixadas:

Creating a Gutenberg block with create-guten-block.
Criando um bloco Gutenberg com create-guten-block

Quando o processo estiver completo, você deve ver a seguinte tela:

Gutenberg block successfully created with create-guten-block.
Bloco Gutenberg criado com sucesso com create-guten-block

Esta próxima imagem mostra a estrutura do projeto com o terminal rodando com o Visual Studio Code:

The block plugin in Visual Studio Code.
O plugin de bloco no Visual Studio Code

.

Agora volte para o seu painel do WordPress. Um novo item deve ser listado na tela Plugins – que é o plugin my-first-block:

The Plugins screen with a new plugin created with create-guten-block.
A tela de Plugins com um novo plugin criado com create-guten-block

Ative o plugin e volte para o terminal. Mude o diretório atual para my-first-block, então execute npm start:

cd my-first-block
npm start

Você deve obter a seguinte resposta:

npm started.
npm começou.

Novamente, isto permite que você execute o plugin no modo de desenvolvimento. Para criar o código de produção, você deve usar:

npm run build

Ative o plugin e crie um novo artigo ou página, depois navegue pelos seus blocos e selecione o seu novo bloco Gutenberg:

A new block created with create-guten-block.
Um novo bloco criado com create-guten-block

Para uma visão mais aprofundada ou em caso de erros, consulte a documentação fornecida por Ahmad Awais.

Uma Introdução rápida do bloco scaffolding

Qualquer uma das duas ferramentas de desenvolvimento – create-block ou create-guten-block – que você optar, você agora tem bloco scaffolding que você pode usar como ponto de partida para construir um plugin de bloco. Mas o que é exatamente um bloco scaffolding?

Bloco scaffolding é um termo curto que descreve a estrutura de diretório de suporte que você precisa para que o WordPress reconheça um bloco. Tipicamente esse diretório inclui arquivos como index.php, index.js, style.css e outros – que, por sua vez, seguram chamadas como register_block_type.

Nós optamos pela ferramenta oficial Create Block dev-tool, como é usada no Manual do Editor de Blocos. Mas mesmo que você decida ir com uma ferramenta de terceiros como create-guten-block, sua experiência não será muito diferente.

Com isso dito, vamos ver detalhadamente a  ferramentacreate-block .

Uma visão detalhada do Bloco Dev-Tool Create

Como mencionamos acima, Create Block é a ferramenta oficial da linha de comando para criar blocos do Gutenberg. Executando @wordpress/create-block em seu terminal, você gera os arquivos PHP, JS e SCSS e o código necessário para registrar um novo tipo de bloco:

npx @wordpress/create-block [options] [slug]

Por padrão, um modelo ESNext é atribuído. Isto significa que você receberá a próxima versão do JavaScript, com a adição da sintaxe JSX.

Se você omitir o nome do bloco, o comando é executado em modo interativo, permitindo que você personalize várias opções antes de gerar os arquivos:

npx @wordpress/create-block
Running create-block in interactive mode.
Executando create-block em modo interativo

A imagem abaixo mostra a estrutura de arquivo de um plugin de bloco criado com a ferramenta oficial Create Block:

Files and folders of a block plugin created with @wordpress/create-block.
Arquivos e pastas de um plugin de bloco criado com @wordpress/create-block

Com isso dito, vamos ver os principais arquivos e pastas do nosso novo plugin de blocos.

O arquivo do Plugin

Com o arquivo principal do plugin você registra o bloco no servidor:

/**
 * Plugin Name: My First Block
 * Description: Example block written with ESNext standard and JSX support – build step required.
 * Requires at least: 5.8
 * Requires PHP: 7.0
 * Version: 0.1.0
 * Author: The WordPress Contributors
 * License: GPL-2.0-or-later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: my-first-block
 *
 * @package create-block
 */
/**
 * Registers the block using the metadata loaded from the `block.json` file.
 * Behind the scenes, it registers also all assets so they can be enqueued
 * through the block editor in the corresponding context.
 *
 * @see https://developer.wordpress.org/block-editor/tutorials/block-tutorial/writing-your-first-block-type/
 */
function create_block_my_first_block_block_init() {
	register_block_type( __DIR__ );
}
add_action( 'init', 'create_block_my_first_block_block_init' );

A função register_block_type registra um tipo de bloco no servidor usando os metadados armazenados no arquivo block.json.

A função leva dois parâmetros:

No código acima, o argumento do tipo de bloco é fornecido pela Constantes Mágicas __DIR__. Isso significa que o arquivo block.json reside na mesma pasta que o arquivo do plugin.

O arquivo package.json

O arquivo package.json define as propriedades e scripts JavaScript para o seu projeto. Aqui é onde você pode instalar as dependências do seu projeto.

Para entender melhor para que serve este arquivo, abra-o com seu editor de código favorito:

{
	"name": "my-first-block",
	"version": "0.1.0",
	"description": "Example block written with ESNext standard and JSX support – build step required.",
	"author": "The WordPress Contributors",
	"license": "GPL-2.0-or-later",
	"main": "build/index.js",
	"scripts": {
		"build": "wp-scripts build",
		"format": "wp-scripts format",
		"lint:css": "wp-scripts lint-style",
		"lint:js": "wp-scripts lint-js",
		"start": "wp-scripts start",
		"packages-update": "wp-scripts packages-update"
	},
	"dependencies": {
		"@wordpress/block-editor": "^7.0.1",
		"@wordpress/blocks": "^11.0.1",
		"@wordpress/i18n": "^4.2.1"
	},
	"devDependencies": {
		"@wordpress/scripts": "^18.0.0"
	}
}

A propriedade scripts é um dicionário que contém comandos que são executados em vários momentos do ciclo de vida de um pacote usando npm run [cmd].

Neste artigo, nós estaremos usando os seguintes comandos:

dependencies e devDependencies são dois objetos que mapeiam um nome de pacote para uma versão. dependencies são necessários na produção, enquanto devDependences são necessários apenas para o desenvolvimento local (leia mais).

A única dependência padrão do dev é o pacote @wordpress/scripts, que é definido como “uma coleção de scripts reutilizáveis feitos sob medida para o desenvolvimento do WordPress”.

O arquivo block.json

Começando com o WordPress 5.8, o arquivo de metadados block.json é a forma canônica de registrar os tipos de blocos.

Ter um arquivo block.json oferece vários benefícios, incluindo melhor desempenho e melhor visibilidade no Diretório de Plugins do WordPress:

De uma perspectiva de desempenho, quando os temas suportam ativos de lazy loading (carregamento preguiçoso), os blocos registrados no block.json terão sua fila de consulta de ativos otimizada fora da caixa. O frontend CSS e os ativos JavaScript listados nas propriedades style ou script só serão consultados quando o bloco estiver presente na página, resultando na redução do tamanho da página.

A execução do comando @wordpress/create-block gera o seguinte arquivo block.json:

{
	"apiVersion": 2,
	"name": "create-block/my-first-block",
	"version": "0.1.0",
	"title": "My First Block",
	"category": "widgets",
	"icon": "smiley",
	"description": "Example block written with ESNext standard and JSX support – build step required.",
	"supports": {
		"html": false
	},
	"textdomain": "my-first-block",
	"editorScript": "file:./build/index.js",
	"editorStyle": "file:./build/index.css",
	"style": "file:./build/style-index.css"
}

Aqui está a lista completa de propriedades padrão:

Além das propriedades listadas acima, você pode (e provavelmente irá) definir um objeto attributes fornecendo informações sobre os dados armazenados pelo seu bloco. Em seu block.json você pode definir qualquer número de atributos em pares chave/valor, onde a chave é o nome do atributo e o valor é a definição do atributo.

Dê uma olhada no seguinte exemplo de definições de atributos:

"attributes": {
	"content": {
		"type": "array",
		"source": "children",
		"selector": "p"
	},
	"align": {
		"type": "string",
		"default": "none"
	},
	"link": { 
		"type": "string", 
		"default": "https://kinsta.com" 
	}
},

Veremos com mais detalhes o arquivo block.json mais tarde no artigo, mas você também pode querer verificar o Manual do Editor de Blocos para informações mais detalhadas sobre os metadados e atributos do block.json.

A pasta src

A pasta src é onde o desenvolvimento acontece. Nessa pasta, você encontrará os seguintes arquivos:

index.js

O arquivo index.js é o seu ponto de partida. Aqui você irá importar dependências e registrar o tipo de bloco no servidor:

import { registerBlockType } from '@wordpress/blocks';
import './style.scss';
import Edit from './edit';
import save from './save';

registerBlockType('create-block/my-first-block', {
	edit: Edit,
	save,
});

A primeira declaração importa a função registerBlockType do pacote @wordpress/blocks. As seguintes declarações de importação importam o stylesheet (folha de estilo) juntamente com as funções Edit e save.

A função registerBlockType registra o componente no cliente. A função toma dois parâmetros: um nome de bloco namespace/block-name (o mesmo que registrado no servidor) e um objeto de configuração de bloco.

A função Edit fornece a interface do bloco como renderizado no editor de blocos, enquanto a função save fornece a estrutura que será serializada e salva no banco de dados (leia mais).

edit.js

edit.js é onde você irá construir a interface de administração do bloco:

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';

export default function Edit() {
	return (
		<p {...useBlockProps()}>
			{__('My First Block – hello from the editor!', 'my-first-block')}
		</p>
	);
}

Primeiro, ele importa a função __ do pacote @wordpress/i18n (este pacote contém uma versão JavaScript das funções de tradução), o hook de Reação useBlockProps, e o arquivo editor.scss.

Depois disso, ele exporta o componente React (leia mais sobre declarações de importação e exportação ).

save.js

O arquivo save.js é onde nós construímos a estrutura do bloco a ser salvo no banco de dados:

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';

export default function save() {
	return (
		<p {...useBlockProps.save()}>
			{__(
				'My First Block – hello from the saved content!',
				'my-first-block'
			)}
		</p>
	);
}

editor.scss e style.scss

Além dos scripts, dois arquivos SASS residem nas pastas src. O arquivo editor.scss contém os estilos aplicados ao bloco no contexto do editor, enquanto o arquivo style.scss contém os estilos do bloco para exibição no frontend. Veremos detalhadamente sobre esses arquivos na segunda parte deste guia.

O node_modules e o build folders

A pasta node_modules contém módulos node e suas dependências. Não entraremos nesse assunto sobre os pacotes para o node, pois está além do escopo deste artigo, mas você pode ler mais neste artigo sobre onde o npm instala os pacotes.

A pasta build contém os arquivos JS e CSS resultantes do processo de construção. Você pode ler mais sobre o processo de construção nos guias ESNext syntax e JavaScript Build Setup.

O Projeto: Construindo seu primeiro bloco do Gutenberg

É hora de sujar nossas mãos. Esta seção ensinará a você como criar um plugin fornecendo um bloco CTA chamado Affiliate Block.

O bloco será composto de duas colunas, com uma imagem à esquerda e um parágrafo de texto à direita. Um botão com um link customizável será colocado abaixo do texto:

The block type you will learn to build in this guide.
O tipo de bloco que você aprenderá a construir neste guia

Este é apenas um exemplo simples, mas nos permite cobrir o básico do desenvolvimento de blocos Gutenberg. Uma vez que você tenha uma compreensão clara do básico, você pode ir em frente e criar blocos Gutenberg cada vez mais complexos com a ajuda do Manual do Editor de Blocos e qualquer outro dos vastos recursos disponíveis lá fora.

Assumindo que você tenha a última versão do WordPress rodando no seu ambiente de desenvolvimento local, aqui está o que você vai aprender daqui em diante:

Prontos… prontos… vamos!

Como configurar o Plugin Starter Block

Inicie sua ferramenta de linha de comando e navegue até a pasta /wp-content/plugins:

New terminal at folder in Mac OS.
Novo terminal em pasta no Mac OS

Agora, execute o seguinte comando:

npx @wordpress/create-block

Este comando gera os arquivos PHP, SCSS e JS para registrar um bloco em modo interativo, permitindo que você adicione facilmente os dados necessários para o seu bloco. Para nosso exemplo vamos usar os seguintes detalhes:

A instalação do plugin e de todas as dependências leva alguns minutos. Quando o processo estiver completo, você verá a seguinte resposta:

The Affiliate block has been installed and registered for development.
O bloco de Afiliados foi instalado e registrado para desenvolvimento

Agora, execute o seguinte comando da pasta /wp-content/plugins:

cd my-affiliate-block

.

Running commands from Visual Studio Code Terminal.
Executando comandos a partir do Visual Studio Code Terminal

Finalmente, de dentro da pasta do seu plugin (my-affiliate-block no nosso exemplo), você pode começar o desenvolvimento com:

npm start

Agora abra a tela Plugins para encontrar e ativar o plugin Affiliate Block:

Affiliate Block plugin.
Plugin Affiliate Block

Crie um novo artigo, abra o inseridor de blocos e desça até a categoria Design. Clique para adicionar o Affiliate Block:

A starter block built with @wordpress/create-block.
Um bloco inicial construído com @wordpress/create-block

block.json em ação

Como mencionamos anteriormente, o registro do bloco do lado do servidor ocorre no arquivo principal .php. Entretanto, nós não vamos definir as configurações no arquivo .php. Ao invés disso, nós estaremos usando o arquivo block.json. Então, abra o block.json novamente e dê uma olhada mais de perto nas configurações padrão:

{
	"apiVersion": 2,
	"name": "my-affiliate-plugin/my-affiliate-block",
	"version": "0.1.0",
	"title": "Affiliate Block",
	"category": "design",
	"icon": "money",
	"description": "An example block for Kinsta readers",
	"supports": {
		"html": false
	},
	"textdomain": "my-affiliate-block",
	"editorScript": "file:./build/index.js",
	"editorStyle": "file:./build/index.css",
	"style": "file:./build/style-index.css"
}

Scripts e estilos

editorScript , editorStyle, e style propriedades fornecem os caminhos relativos aos scripts e estilos frontend e backend. Você não precisa registrar manualmente os scripts e estilos definidos aqui porque estes são automaticamente registrados e consultados pelo WordPress. Para provar isso, abra o inspetor do navegador e abra a aba Rede:

Inspecting resources in Chrome DevTools.
Inspecionando recursos nas ferramentas de cromagem

Como você pode ver na imagem acima, nosso script index.js residente na pasta de construção tem sido regularmente consultado sem a necessidade de adicionar qualquer código PHP.

Etiquetas UI

As propriedades title e description fornecem etiquetas necessários para identificar o bloco no editor:

Block name and description in the block sidebar.
Nome e descrição do bloco na barra lateral do bloco

Palavras-chave

Como mencionamos anteriormente, você pode configurar com precisão suas configurações de bloco usando propriedades e atributos. Por exemplo, você pode adicionar um ou mais keywords para ajudar os usuários a pesquisar blocos:

{ "keywords": [ "kinsta", "affiliate", "money" ] }

Se você agora inserir “kinsta”, “afiliado” ou “dinheiro” no inseridor rápido, o editor irá sugerir a você o bloco de afiliados:

Searching for a block using a keyword in the quick inserter.
Procura de um bloco usando uma palavra-chave no inseridor rápido

Localização

Se você está se perguntando como a localização das strings no arquivo JSON acontece, aqui está a resposta:

Em JavaScript, você pode usar agora o método registerBlockTypeFromMetadata do pacote @wordpress/blocks para registrar um tipo de bloco usando os metadados carregados do arquivo block.json. Todas as propriedades localizadas são automaticamente envolvidas em _x (do pacote @wordpress/i18n ) chamadas de função similares a como funciona em PHP com register_block_type_from_metadata. O único requisito é definir a propriedade textdomain no arquivo block.json.

Aqui nós estamos usando a função registerBlockType ao invés de registerBlockTypeFromMetadata, pois esta última foi depreciada desde o Gutenberg 10.7, mas o mecanismo é o mesmo.

Usando componentes incorporados: O componente RichText

Os elementos que compõem um bloco do Gutenberg são os componentes React, e você pode acessar esses componentes através da variável global wp. Por exemplo, tente digitar wp.editor no console do seu navegador. Isto lhe dará a lista completa dos componentes incluídos no módulo wp.editor. Percorra a lista e adivinhe para que componentes são destinados por seus nomes. Da mesma forma, você pode verificar a lista de componentes incluídos no módulo wp.components:

WP Editor components.
Componentes do WP Editor

.

Agora volte para o arquivo edit.js e dê uma olhada mais de perto no script:

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';

export default function Edit() {
	return (
		<p {...useBlockProps()}>
			{__('My First Block – hello from the editor!', 'my-first-block')}
		</p>
	);
}

Este código gera um bloco estático com texto simples e não editável. Mas nós podemos mudar as coisas facilmente:

The starter block in the code editor.
O bloco de partida no editor de código

Para tornar o texto editável, você terá que substituir a tag <p> atual por um componente que torne o conteúdo de entrada editável. Para isso, o Gutenberg fornece o componente RichText embutido.

Adicionar um componente incorporado ao seu bloco é um processo de 5 passos:

  1. Importe os componentes necessários de um pacote WordPress
  2. Inclua os elementos correspondentes em seu código JSX
  3. Defina os atributos necessários no arquivo block.json
  4. Defina os manipuladores de eventos
  5. Salve os dados

Passo 1: Importe os componentes necessários de um pacote WordPress

Agora abra o arquivo edit.js e mude o seguinte comando import:

import { useBlockProps } from '@wordpress/block-editor';

…para:

import { useBlockProps, RichText } from '@wordpress/block-editor';

Desta forma, você está importando a função useBlockProps e o componente RichText do pacote @wordpress/block-editor.

useBlockProps

O useBlockProps e o hook de reação marca o elemento de invólucro do bloco:

Ao usar a API versão 2, você deve usar o novo hook useBlockProps na função edit do bloco para marcar o elemento de invólucro do bloco. O hook irá inserir atributos e manipuladores de eventos necessários para habilitar o comportamento do bloco. Quaisquer atributos que você queira passar para o elemento de bloco devem ser passados por useBlockProps e o valor retornado deve ser espalhado para o elemento.

Para simplificar, useBlockProps atribui automaticamente atributos e classes ao elemento invólucro (o elemento p em nosso exemplo):

Elements and classes generated by useBlockProps.
Elementos e classes gerados pelo usoBlockProps

Se você remover useBlockProps do elemento do pacote, você terá uma simples sequência do texto sem acesso à funcionalidade e estilo de bloqueio:

The same block without useBlockProps.
O mesmo bloco sem usarBlockProps

Como explicaremos mais tarde, você também pode passar para useBlockProps um objeto de propriedades para personalizar a saída.

RichText

O componente RichText fornece uma entrada de conteúdo que permite aos usuários editar e formatar o conteúdo. Você encontrará o componente documentado no GitHub em gutenberg/packages/block-editor/src/components/rich-text/README.md.

Passo 2: Inclua os elementos correspondentes em seu código JSX

...

const blockProps = useBlockProps();

return (
	<RichText 
		{ ...blockProps }
		tagName="p"
		onChange={ onChangeContent }
		allowedFormats={ [ 'core/bold', 'core/italic' ] }
		value={ attributes.content }
		placeholder={ __( 'Write your text...' ) }
	/>
);

Vamos comentar sobre o código linha por linha:

Passo 3: Defina os atributos necessários no arquivo block.json

Atributos fornecem informações sobre os dados armazenados por um bloco, tais como conteúdo rico, cor de fundo, URLs, etc.

Você pode definir um número arbitrário de atributos dentro de um objeto attributes em pares chave/valor, onde a chave é o nome do atributo e o valor é a definição do atributo.

Agora abra o arquivo block.json e adicione o seguinte attributes prop:

"attributes": {
	"content": {
		"type": "string",
		"source": "html",
		"selector": "p"
	}
},

O atributo content permite armazenar o texto digitado pelo usuário no campo editável:

Nós iremos passar a função Edit como objeto de propriedades. Então, volte para o arquivo edit.js e faça a seguinte mudança:

export default function Edit( { attributes, setAttributes } ) { ... }

Etapa 4: Defina os manipuladores de eventos

O elemento RichText tem um atributo onChange, fornecendo uma função a ser chamada quando o conteúdo do elemento muda.

Vamos definir essa função e ver todo o script do edit.js:

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';
import './editor.scss';

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();

	const onChangeContent = ( newContent ) => {
		setAttributes( { content: newContent } )
	}

	return (
		<RichText 
			{ ...blockProps }
			tagName="p"
			onChange={ onChangeContent }
			allowedFormats={ [ 'core/bold', 'core/italic' ] }
			value={ attributes.content }
			placeholder={ __( 'Write your text...' ) }
		/>
	);
}

Agora salve o arquivo e execute npm run start na janela do seu terminal. Então, volte ao seu painel do WordPress, crie um novo artigo ou página e adicione seu bloco de Afiliados:

The output of the RichText component in the Block Editor.
A saída do componente RichText no Editor de Blocos

Adicione algum texto e mude para a visualização de código. Aqui está como o seu código deve ser:

<!-- wp:my-affiliate-plugin/my-affiliate-block -->
<p class="wp-block-my-affiliate-plugin-my-affiliate-block">This is my first editable Gutenberg block 🤓</p>
<!-- /wp:my-affiliate-plugin/my-affiliate-block -->

Se você agora salvar a página e verificar o resultado do frontend, você pode ficar um pouco desapontado porque suas mudanças não afetam o site. Isso porque você tem que modificar o arquivo save.js para armazenar a entrada do usuário no banco de dados quando o artigo é salvo.

Passo 5: Salve os dados

Agora abra o arquivo save.js e mude o script da seguinte forma:

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ attributes.content } 
		/>
	);
}

Isso é o que estamos fazendo aqui:

.

Você pode ler mais sobre o componente RichText no Block Editor Handbook e encontrar a lista completa de adereços no Github. Agora vamos dar um passo adiante.

Na próxima seção, você aprenderá como adicionar controles à barra de ferramentas do bloco.

Adicionando controles à barra de ferramentas de bloqueio

A barra de ferramentas do bloco contém um conjunto de controles que permite aos usuários manipularem partes do conteúdo do bloco. Para cada controle da barra de ferramentas, você encontrará um componente:

The core paragraph block toolbar.
A barra de ferramentas do bloco de parágrafos centrais

Por exemplo, você poderia adicionar um controle de alinhamento de texto para o seu bloco. Tudo o que você precisa fazer é importar dois componentes do pacote @wordpress/block-editor.

Nós vamos passar pelos mesmos passos do exemplo anterior:

  1. Importe os componentes necessários de um pacote WordPress
  2. Inclua os elementos correspondentes em seu código JSX
  3. Defina os atributos necessários no arquivo block.json
  4. Defina os manipuladores de eventos
  5. Salve os dados

Passo 1: Importação de componentes BlockControls e AlignmentControl de @wordpress/block-editor

Para adicionar um controle de alinhamento à barra de ferramentas do bloco, você precisa de dois componentes:

Abra o arquivo edit.js e edite a declaração import como mostrado abaixo:

Cansado do suporte de hospedagem do WordPress de nível 1 sem as respostas? Experimente nossa equipe de suporte de classe mundial! Confira nossos planos

import { 
	useBlockProps, 
	RichText, 
	AlignmentControl, 
	BlockControls 
} from '@wordpress/block-editor';

Passo 2: Adicione elementos BlockControls e AlignmentControl

Vá para a função Edit e insira o elemento <BlockControls /> no mesmo nível que <RichText />. Depois adicione e <AlignmentControl /> dentro do <BlockControls />:

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();
	return (
		<>
			<BlockControls>
				<AlignmentControl
					value={ attributes.align }
					onChange={ onChangeAlign }
				/>
			</BlockControls>
			<RichText 
				{ ...blockProps }
				tagName="p"
				onChange={ onChangeContent }
				allowedFormats={ [ 'core/bold', 'core/italic' ] }
				value={ attributes.content }
				placeholder={ __( 'Write your text...' ) }
				style={ { textAlign: attributes.align } }
			/>
		</>
	);
}

No código acima, <> e </> são a breve sintaxe para declarar fragmentos do React, que é como retornamos múltiplos elementos no React.

Neste exemplo, AlignmentControl tem dois atributos:

Nós também definimos atributos adicionais para o elemento RichText (veja a lista completa de atributos com exemplos)

Passo 3: Defina o atributo de alinhamento no block.json

Agora vá para o arquivo block.json e adicione o atributo align:

"align": {
	"type": "string",
	"default": "none"
}

Volte para o terminal, pare o processo atual com ^C e inicie o script novamente com npm run start. Depois volte para o editor de blocos, atualize a página e selecione o bloco. Você deve ver a barra de ferramentas do bloco com um controle de alinhamento:

The Alignment Toolbar has been successfully added.
A Barra de Ferramentas de Alinhamento foi adicionada com sucesso

Agora, se você tentar formatar o conteúdo do bloco usando os novos controles de alinhamento, você verá que nada acontece. Isso porque nós ainda não definimos o manipulador do evento.

Passo 4: Defina os manipuladores de eventos

Agora defina onChangeAlign:

const onChangeAlign = ( newAlign ) => {
	setAttributes( { 
		align: newAlign === undefined ? 'none' : newAlign, 
	} )
}

Se newAlign é undefined, então nós definimos newAlign para none. Caso contrário, nós usamos newAlign.

Nosso script edit.js deve estar completo (por enquanto):

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();
	const onChangeContent = ( newContent ) => {
		setAttributes( { content: newContent } )
	}
	const onChangeAlign = ( newAlign ) => {
		setAttributes( { 
			align: newAlign === undefined ? 'none' : newAlign, 
		} )
	}
	return (
		<>
			<BlockControls>
				<AlignmentControl
					value={ attributes.align }
					onChange={ onChangeAlign }
				/>
			</BlockControls>
			<RichText 
				{ ...blockProps }
				tagName="p"
				onChange={ onChangeContent }
				allowedFormats={ [ 'core/bold', 'core/italic' ] }
				value={ attributes.content }
				placeholder={ __( 'Write your text...' ) }
				style={ { textAlign: attributes.align } }
			/>
		</>
	);
}

Agora você pode voltar para o editor e alinhar o conteúdo do bloco.

Nós precisamos modificar a função salvar para armazenar o conteúdo e os atributos do bloco no banco de dados.

Passo 5: Salve os dados

Abra o save.js e mude a função save da seguinte forma:

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ attributes.content } 
			style={ { textAlign: attributes.align } }
		/>
	);
}

Finalmente, para tornar o código mais legível, você pode extrair as propriedades individuais do objeto attribute usando a sintaxe de atribuição de desestruturação:

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	const { content, align } = attributes;
	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ content } 
			style={ { textAlign: align } }
		/>
	);
}

Salve o arquivo, reinicie o processo e retorne ao editor no modo editor de código. O código deve ser algo parecido com isto:

<!-- wp:my-affiliate-plugin/my-affiliate-block {"align":"right"} -->
<p class="wp-block-my-affiliate-plugin-my-affiliate-block" style="text-align:right">This is my first editable <strong><em>Gutenberg</em></strong> <em>block</em> 🤓</p>
<!-- /wp:my-affiliate-plugin/my-affiliate-block -->
Align text right.
Alinhe o texto corretamente.

É isso aí! Você acabou de adicionar um controle de alinhamento à barra de ferramentas do bloco 🤓

Você pode ler mais sobre os controles da barra de ferramentas de blocos no Manual do Editor de Blocos.

Personalizando a barra lateral de configurações de blocos

Você também pode adicionar controles ao bloco configurações da barra lateral (ou até mesmo criar uma nova barra lateral para o seu aplicativo).

A API fornece um componenteInspectorControls para isso.

O Manual do Editor de Blocos explica como usar a Barra Lateral de Configurações:

A Barra lateral de configurações é usada para exibir configurações menos utilizadas ou configurações que requerem mais espaço na tela. A Barra lateral de configurações deve ser usada somente para configurações de nível de bloco.

Se você tem configurações que afetam apenas o conteúdo selecionado dentro de um bloco (exemplo: a configuração “negrito” para o texto selecionado dentro de um parágrafo): não o coloque dentro da barra lateral de configurações. A Barra lateral de configurações é exibida mesmo quando se edita um bloco no modo HTML, então ela só deve conter configurações de nível de bloco.

Novamente:

  1. Importe os componentes necessários de um pacote WordPress
  2. Inclua os elementos correspondentes em seu código JSX
  3. Defina os atributos necessários no arquivo block.json
  4. Defina os manipuladores de eventos
  5. Salve os dados

Passo 1. Importe os componentes InspectorControls e PanelColorSettings do @wordpress/block-editor

Você pode adicionar vários controles para permitir que os usuários personalizem aspectos específicos do bloco. Por exemplo, você pode fornecer um painel de controle colorido. Para fazer isso, você precisará importar os componentes InspectorControls e PanelColorSettings do módulo block-editor:

import { 
	useBlockProps, 
	RichText, 
	AlignmentControl, 
	BlockControls,
	InspectorControls,
	PanelColorSettings
} from '@wordpress/block-editor';

Passo 2: Inclua os elementos correspondentes em seu código JSX

Agora você pode adicionar os elementos correspondentes ao JSX retornado pela função Edit:

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();
	const onChangeContent = ( newContent ) => {
		setAttributes( { content: newContent } )
	}
	const onChangeAlign = ( newAlign ) => {
		setAttributes( { 
			align: newAlign === undefined ? 'none' : newAlign, 
		} )
	}
	return (
		<>
			<InspectorControls>
				<PanelColorSettings 
					title={ __( 'Color settings', 'my-affiliate-block' ) }
					initialOpen={ false }
					colorSettings={ [
						{
						  value: textColor,
						  onChange: onChangeTextColor,
						  label: __( 'Text color', 'my-affiliate-block' ),
						},
						{
						  value: backgroundColor,
						  onChange: onChangeBackgroundColor,
						  label: __( 'Background color', 'my-affiliate-block' ),
						}
					] }
				/>
			</InspectorControls>
			<BlockControls>
				<AlignmentControl
					value={ attributes.align }
					onChange={ onChangeAlign }
				/>
			</BlockControls>
			<RichText 
				{ ...blockProps }
				tagName="p"
				onChange={ onChangeContent }
				allowedFormats={ [ 'core/bold', 'core/italic' ] }
				value={ attributes.content }
				placeholder={ __( 'Write your text...', 'my-affiliate-block' ) }
				style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
			/>
		</>
	);
}

Note que nós também atualizamos o atributo style do elemento RichText:

<RichText 
	 { ...blockProps }
	 tagName="p"
	 onChange={ onChangeContent }
	 allowedFormats={ [ 'core/bold', 'core/italic' ] }
	 value={ content }
	 placeholder={ __( 'Write your text...', 'my-affiliate-block' ) }
	 style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
/>

Passo 3: Defina os atributos necessários no block.json

Agora defina os atributos backgroundColor e textColor no arquivo block.json:

"attributes": {
	"content": {
		"type": "string",
		"source": "html",
		"selector": "p"
	},
	"align": {
		"type": "string",
		"default": "none"
	},
	"backgroundColor": {
		"type": "string"
	},	 
	"textColor": {
		"type": "string"
	}
},

Etapa 4: Defina os manipuladores de eventos

Agora você precisa definir duas funções para atualizar backgroundColor e textColor na entrada do usuário:

const onChangeBackgroundColor = ( newBackgroundColor ) => {
	setAttributes( { backgroundColor: newBackgroundColor } )
}
const onChangeTextColor = ( newTextColor ) => {
	setAttributes( { textColor: newTextColor } )
}

Passo 5: Salve os dados

Um último passo: Abra o arquivo save.js e mude o script como a seguir:

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	const { content, align, backgroundColor, textColor } = attributes;
	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ content } 
			style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
		/>
	);
}

Agora pare o processo (^C) e execute novamente npm run start. Atualize a página, apague qualquer instância do seu bloco e adicione-a novamente ao seu artigo:

A custom block with a Color Settings panel.
Um bloco personalizado com um painel de configurações de cores

Faça suas mudanças, salve o artigo e visualize-o no frontend. As mudanças que você fez no editor de blocos devem ser refletidas no front site.

Nesta seção, você irá adicionar novos componentes ao seu tipo de bloco:

Passo 1. Importe os componentes do @wordpress/componentes

Agora você precisa importar vários componentes do @wordpress/components. Abra seu arquivo edit.js e adicione a seguinte declaração import:

import {
	TextControl,
	PanelBody,
	PanelRow,
	ToggleControl,
	ExternalLink
} from '@wordpress/components';

Passo 2. Inclua os elementos correspondentes em seu código JSX

Primeiro você adicionará o elemento ExternalLink no mesmo nível de RichText em um contêiner div:

<div { ...blockProps }>
	<RichText 
		...
	/>
	<ExternalLink 
		href={ affiliateLink }
		className="affiliate-button"
		rel={ hasLinkNofollow ? "nofollow" : "" }
	>
			{ linkLabel }
	</ExternalLink>

</div>

O componente ExternalLink não está documentado, então nós nos referimos ao próprio componente para obter a lista de atributos disponíveis. Aqui nós estamos usando os atributos href, className e rel.

Por padrão, o valor do atributo rel está definido para noopener noreferrer. Nosso código irá adicionar a palavra-chavenofollow ao atributo rel da tag a resultante quando o controle de alternância estiver ligado.

Agora você pode adicionar configurações de link à barra lateral do bloco.

Primeiro, você adicionará um elemento PanelBody dentro de InspectorControls no mesmo nível do PanelColorSettings:

<InspectorControls>
	<PanelColorSettings 
	...
	/>
	<PanelBody 
		title={ __( 'Link Settings', 'my-affiliate-block' )}
		initialOpen={true}
	>
	...
	</PanelBody>
</InspectorControls>

Aqui está o que estamos fazendo com isto:

  1. O atributo title fornece o título do painel.
  2. initialOpen define se o painel está ou não inicialmente aberto.

Em seguida, vamos adicionar dois elementos PanelRow dentro de PanelBody, e um elemento TextControl dentro de cada PanelRow:

<PanelBody 
	title={ __( 'Link Settings', 'my-affiliate-block' )}
	initialOpen={true}
>
	<PanelRow>
		<fieldset>
			<TextControl
				label={__( 'Affiliate link', 'my-affiliate-block' )}
				value={ affiliateLink }
				onChange={ onChangeAffiliateLink }
				help={ __( 'Add your affiliate link', 'my-affiliate-block' )}
			/>
		</fieldset>
	</PanelRow>
	<PanelRow>
		<fieldset>
			<TextControl
				label={__( 'Link label', 'my-affiliate-block' )}
				value={ linkLabel }
				onChange={ onChangeLinkLabel }
				help={ __( 'Add link label', 'my-affiliate-block' )}
			/>
		</fieldset>
	</PanelRow>
</PanelBody>

O código acima deve agora parecer bastante simples. Os dois controles de texto permitem que os usuários definam o rótulo e a URL do link.

Nós também adicionaremos um adicional PanelRow com um ToggleControl para ligar/desligar uma opção específica, como a inclusão ou não de um atributo:

<PanelRow>
	<fieldset>
		<ToggleControl
			label="Add rel = nofollow"
			help={
				hasLinkNofollow
					? 'Has rel nofollow.'
					: 'No rel nofollow.'
			}
			checked={ hasLinkNofollow }
			onChange={ toggleNofollow }
		/>
	</fieldset>
</PanelRow>

Passo 3: Defina os atributos necessários no block.json

Agora defina os atributos affiliateLink, linkLabel, e hasLinkNofollow no arquivo block.json:

"affiliateLink": {
	"type": "string",
	"default": ""
},
"linkLabel": {
	"type": "string",
	"default": "Check it out!"
},
"hasLinkNofollow": {
	"type": "boolean",
	"default": false
}

Nada mais a acrescentar aqui! Vamos passar para a definição das funções de tratamento de eventos.

Passo 4: Defina os manipuladores de eventos

Volte para o arquivo edit.js e adicione as seguintes funções:

const onChangeAffiliateLink = ( newAffiliateLink ) => {
	setAttributes( { affiliateLink: newAffiliateLink === undefined ? '' : newAffiliateLink } )
}

const onChangeLinkLabel = ( newLinkLabel ) => {
	setAttributes( { linkLabel: newLinkLabel === undefined ? '' : newLinkLabel } )
}

const toggleNofollow = () => {
	setAttributes( { hasLinkNofollow: ! hasLinkNofollow } )
}

Estas funções atualizam os valores dos atributos correspondentes na entrada do usuário.

Passo 5: Salve os dados

Por último, temos que atualizar a função save no save.js:

export default function save( { attributes } ) {

	const { align, content, backgroundColor, textColor, affiliateLink, linkLabel, hasLinkNofollow } = attributes;

	const blockProps = useBlockProps.save();

	return (
		<div { ...blockProps }>
			<RichText.Content 
				tagName="p" 
				value={ content } 
				style={ { backgroundColor: backgroundColor, color: textColor } }
			/>
			<p>
				<a 
					href={ affiliateLink }
					className="affiliate-button"
					rel={ hasLinkNofollow ? "nofollow" : "noopener noreferrer" }
				>
					{ linkLabel }
				</a>
			</p>
		</div>
	);
}

Note que aqui nós usamos um elemento regular a ao invés de ExternalLink:

Affiliate block link settings.
Configurações de link de bloco de afiliados

Agora salve os dados e reinicie seu ambiente.

Adicionando múltiplos estilos de bloco

Em uma seção anterior, você aprendeu como adicionar um controle de barra de ferramentas de bloco permitindo que os usuários alinhem a entrada do usuário. Nós podemos adicionar mais controles de estilo à barra de ferramentas do bloco, mas também podemos fornecer um conjunto de estilos de bloco predefinidos que o usuário pode escolher com um único clique.

Para este propósito, nós vamos usar um recurso útil do API do Bloco: Estilos de Bloco.

Tudo o que você precisa fazer é definir a propriedade block.json styles e declarar os estilos correspondentes no stylesheets (folhas de estilo).

Por exemplo, você pode adicionar a seguinte gama de estilos:

"styles": [
	{
		"name": "default",
		"label": "Default",
		"isDefault": true
	},
	{
		"name": "border",
		"label": "Border"
	}
],

Com isso, você acabou de adicionar um estilo padrão e um estilo adicional chamado border. Agora volte para o editor de blocos:

Two predefined block styles.
Dois estilos de blocos predefinidos

Os estilos estarão disponíveis para o usuário clicando na chave de bloco e depois procurando pelo Styles panel na Block Settings Sidebar.

Selecione um estilo e verifique as classes aplicadas ao elemento p. Clique com o botão direito do mouse sobre o bloco e Inspect. Uma nova classe foi adicionada com um nome estruturado como a seguir:

is-style-{style-name}

Se você verificou o estilo “Border”, então uma classe is-style-border será adicionada ao elemento p. Se você marcou o estilo “Default”, então uma classe is-style-default será adicionada ao invés disso.

Agora você só tem que declarar as propriedades do CSS. Abra o arquivo editor.scss e substitua os estilos atuais com o seguinte:

.wp-block-my-affiliate-plugin-my-affiliate-block {
	padding: 2px;
	&.is-style-default{
		border: 0;
	}
	&.is-style-border{
		border: 1px solid #000;
	}
}

Agora você pode fazer o mesmo com style.scss:

.wp-block-my-affiliate-plugin-my-affiliate-block {
	&.is-style-default{
		border: 0;
	}
	&.is-style-border{
		border: 1px solid #000;
	}
}

Pare o processo (^C) e execute novamente npm run start.

E é isso aí! Refresque a página, e divirta-se com seus novos estilos de blocos:

Affiliate block styles.
Estilos de blocos de afiliados

Agrupando blocos Gutenberg com o componente InnerBlocks

Embora totalmente funcional, nosso Bloco de Afiliados ainda não é muito atraente. Para torná-lo mais atrativo para o público, nós poderíamos adicionar uma imagem.

Isto pode acrescentar uma camada de complexidade ao nosso bloco, mas felizmente, você não precisa reinventar a roda porque Gutenberg fornece um componente específico que você pode usar para criar uma estrutura de blocos agrupados.

O componente InnerBlocks é definido da seguinte forma:

OInnerBlocks exporta um par de componentes que podem ser usados em implementações de blocos para permitir o conteúdo de blocos agrupados.

Primeiro, você precisará criar um novo arquivo .js na pasta src. Em nosso exemplo, nós chamaremos este arquivo container.js.

Agora você precisará importar o novo recurso para o arquivo index.js:

import './container';

Volte para container.js e importe os componentes necessários:

import { registerBlockType } from "@wordpress/blocks";
import { __ } from "@wordpress/i18n";
import {
	useBlockProps, 
	InnerBlocks 
} from "@wordpress/block-editor";

O próximo passo é definir um modelo fornecendo a estrutura dentro da qual os blocos serão colocados. No exemplo a seguir, nós definimos um modelo que consiste de duas colunas contendo um bloco de Imagem central e nosso bloco de Afiliados personalizado:

const TEMPLATE = [ [ 'core/columns', { backgroundColor: 'yellow', verticalAlignment: 'center' }, [
	[ 'core/column', { templateLock: 'all' }, [
		[ 'core/image' ],
	] ],
	[ 'core/column', { templateLock: 'all' }, [
		[ 'my-affiliate-plugin/my-affiliate-block', { placeholder: 'Enter side content...' } ],
	] ],
] ] ];

O modelo é estruturado como um conjunto de tipos de bloco (nome do bloco e atributos opcionais).

No código acima, usamos vários atributos para configurar as Colunas e Blocos de Colunas. Especificamente, o atributo templateLock: 'all' bloqueia os blocos de colunas para que o usuário não adicione, reordene ou exclua blocos existentes. templateLock pode assumir um dos seguintes valores:

O modelo é então designado para o elemento InnerBlocks:

<InnerBlocks
	template={ TEMPLATE }
	templateLock="all"
/>

Para evitar qualquer problema de compatibilidade, nós também adicionamos um atributo templateLock ao componente InnerBlocks (veja também o número #17262 e o número #26128).

Aqui está nosso arquivo final container.js:

import { registerBlockType } from "@wordpress/blocks";
import { __ } from "@wordpress/i18n";
import { useBlockProps, InnerBlocks } from "@wordpress/block-editor";

const TEMPLATE = [ [ 'core/columns', { backgroundColor: 'yellow', verticalAlignment: 'center' }, [
	[ 'core/column', { templateLock: 'all' }, [
		[ 'core/image' ],
	] ],
	[ 'core/column', { templateLock: 'all' }, [
		[ 'my-affiliate-plugin/my-affiliate-block', { placeholder: 'Enter side content...' } ],
	] ],
] ] ];

registerBlockType('my-affiliate-plugin/my-affiliate-container-block', {
	title: __( 'Container', 'my-affiliate-block' ),
	category: 'design',

	edit( { className } ) {
		
		return(
			<div className={ className }>
				<InnerBlocks
					template={ TEMPLATE }
					templateLock="all"
				/>
			</div>
		)
	},

	save() {
		const blockProps = useBlockProps.save();
		return(
			<div { ...blockProps }>
				<InnerBlocks.Content />
			</div>
		)
	},
});
The nested Affiliate block in the editor.
O bloco de afiliados agrupados no editor

Melhorias adicionais

Nosso bloco é totalmente funcional, mas nós poderíamos melhorá-lo um pouco com algumas pequenas mudanças.

Nós atribuímos o atributo backgroundColor ao parágrafo gerado pelo componente RichText. Entretanto, podemos preferir atribuir a cor de fundo ao recipiente div:

Então, mude o arquivo edit.js e salve.js divs da seguinte forma:

<div 
	{ ...blockProps }
	style={ { backgroundColor: backgroundColor } }
>
...
</div>

Isto permitirá que o usuário mude o fundo do bloco inteiro.

Por outro lado, uma mudança mais relevante envolve o método useBlockProps. No código original, nós definimos a constante blockProps como segue:

const blockProps = useBlockProps();

Mas nós podemos usar o useBlockProps mais efetivamente passando um conjunto de propriedades. Por exemplo, nós podemos importar classnames do módulo classnames e definir o nome da classe do pacote de acordo.

No exemplo a seguir, nós atribuímos um nome de classe baseado no valor do atributo align (edit.js):

import classnames from 'classnames';

...

export default function Edit( { attributes, setAttributes } ) {
	...
	const blockProps = useBlockProps( {
		className: classnames( {
			[ `has-text-align-${ align }` ]: align,
		} )
	} );
	...
}

Nós faremos a mesma mudança no arquivo save.js:

import classnames from 'classnames';

...

export default function save( { attributes } ) {
	...
	const blockProps = useBlockProps.save({
		className: classnames( {
			[ `has-text-align-${ align }` ]: align,
		} )
	});
	...
}

E isso é um final! Agora você pode executar o desenvolvimento para produção.

Se você está procurando por um guia detalhado para começar a desenvolver blocos Gutenberg, este guia é para você. Confira e comece a construir seus blocos Gutenberg hoje mesmo! 👷‍♀️🧱Click to Tweet

Resumo

E aqui estamos nós, no final desta incrível jornada! Nós começamos com a configuração do ambiente de desenvolvimento e acabamos criando um tipo de bloco completo.

Como mencionamos na introdução, um conhecimento sólido do Node.js, Webpack, Babel e React é essencial para criar blocos Gutenberg avançados e se posicionar no mercado como um desenvolvedor Gutenberg profissional.

Mas você não precisa ter experiência de React estabelecida para começar a se divertir com o desenvolvimento de blocos. O desenvolvimento de blocos pode lhe dar motivação e objetivos para ganhar habilidades cada vez mais amplas nas tecnologias por trás dos blocos Gutenberg.

Este guia, portanto, está longe de ser completo. É apenas uma introdução a uma grande variedade de tópicos que irão ajudá-lo a começar a construir seus primeiros blocos Gutenberg.

Por esta razão, nós recomendamos que você aprofunde seu conhecimento lendo cuidadosamente a documentação e os guias online. Entre os muitos recursos disponíveis lá fora, nós recomendamos o seguinte:

Se você está apenas começando com o desenvolvimento do WordPress, você pode querer entender os conceitos básicos de desenvolvimento frontend. Aqui está uma lista rápida de recursos que podem ajudar você a começar:

E lembre-se que o código completo dos exemplos deste guia está disponível no Gist.


Economize tempo, custos e otimize o desempenho do seu site com:

  • Ajuda instantânea de especialistas em hospedagem do WordPress, 24/7.
  • Integração do Cloudflare Enterprise.
  • Alcance global com 29 centros de dados em todo o mundo.
  • Otimização com nosso monitoramento integrado de desempenho de aplicativos.

Tudo isso e muito mais em um plano sem contratos de longo prazo, migrações assistidas e uma garantia de 30 dias de devolução do dinheiro. Confira nossos planos ou entre em contato com as vendas com as vendas para encontrar o plano certo para você.