Você ainda está perplexo com o Gutenberg? Ou você está entre aqueles que acreditam firmemente no potencial do editor de blocos e querem descobrir até onde podem levar a criatividade deles usando o editor de blocos?

Qualquer que seja a categoria de usuários em que você se encaixe, o Gutenberg está aqui para ficar e este artigo lhe dará uma visão aprofundada do que acontece nos bastidores do editor de blocos do WordPress. Mas isso não é tudo!

Seguindo nosso tutorial anterior onde fornecemos uma introdução geral ao desenvolvimento de blocos do Gutenberg, este artigo vai além do básico, introduzindo tipos de blocos mais avançados. Estes blocos são chamados de blocos dinâmicos.

Hoje você vai aprender o que são blocos dinâmicos, como eles funcionam e tudo o que você precisa saber para criar blocos dinâmicos do zero.

Então, quais são os blocos dinâmicos de Gutenberg, e quais são as principais diferenças entre os blocos estáticos e dinâmicos?

O que são blocos dinâmicos? Um exemplo

Enquanto com blocos estáticos o conteúdo é adicionado manualmente pelo usuário durante a edição de um artigo ou página, com blocos dinâmicos o conteúdo é carregado e processado na hora de carregar a página. Com blocos dinâmicos, o conteúdo do bloco é retirado do banco de dados e exibido como é ou resultante de qualquer tipo de manipulação de dados.

Vamos explicar isso com um exemplo. Digamos que você queira criar um grupo de blocos agrupados mostrando detalhes do autor do artigo com uma seleção dos últimos artigos do mesmo autor.

Um bloco de grupo incluindo Autor do Artigo e Últimos Artigos
Um bloco de grupo incluindo Autor do Artigo e Últimos Artigos

Como usuários do Gutenberg, você poderia usar os seguintes blocos:

  • O bloco central do Heading
  • O bloco central Autor do artigo
  • O bloco central de Artigos mais recentes

Você também poderia criar um grupo incluindo esses blocos e adicionar o grupo a blocos reutilizáveis para uso futuro.

Adicionando um bloco de grupo a blocos reutilizáveis
Adicionando um bloco de grupo a blocos reutilizáveis

É bastante simples, não é? Você pode criar um bloco dinâmico e adicioná-lo aos seus artigos e páginas em um piscar de olhos.

A partir do WordPress 5.9, o editor de blocos fornece mais de 90 blocos diferentes, e as chances são de que você encontre o bloco certo para você, logo de cara. E, se você precisar de mais, faça uma busca rápida no diretório de plugins do WordPress e você encontrará um monte de plugins gratuitos fornecendo blocos adicionais.

Mas e se você é um desenvolvedor WordPress – ou está planejando uma carreira como um desenvolvedor WordPress? Talvez você tenha necessidades muito específicas e não consiga encontrar o bloco que você está procurando, ou simplesmente queira adquirir novas habilidades profissionais. Em tais situações, você pode querer aprender como criar seus blocos dinâmicos.

Blocos dinâmicos de Gutenberg do ponto de vista do desenvolvedor

Os blocos dinâmicos têm dois casos de uso principal.

O primeiro caso de uso é quando você precisa atualizar o conteúdo de um bloco quando a página que contém o bloco não foi atualizada. Por exemplo, isto acontece quando o bloco inclui uma lista dos últimos artigos ou comentários, e em geral sempre que o conteúdo do bloco é gerado dinamicamente usando dados recuperados do banco de dados.

Adicionando um bloco de consulta em loop
Adicionando um bloco de consulta em loop

O segundo caso de uso é quando uma atualização do código do bloco precisa ser mostrada imediatamente no frontend. Usar um bloco dinâmico ao invés de um bloco estático faz com que as mudanças sejam imediatamente aplicadas a todas as ocorrências do bloco.

Por outro lado, se você mudar o HTML produzido por um bloco estático, o usuário verá um diálogo de invalidação até que cada instância da versão anterior do bloco seja removida e substituída pela nova versão, ou você marca a versão antiga como depreciada (veja também Deprecation and Block Validation, Deprecation and Migration Experience).

Conteúdo inesperado ou inválido.
Conteúdo inesperado ou inválido

Dito isto, há alguns conceitos que você precisa entender antes de começar a construir blocos dinâmicos.

Status do aplicativo e armazenamento de dados

Gutenberg é um aplicativo React SPA, e tudo em Gutenberg é um componente React. Título do artigo, cabeçalhos, parágrafos, imagens e qualquer bloco de conteúdo HTML no editor é um componente React, assim como controles da barra lateral e da barra de ferramentas do bloco.

Em nosso artigo anterior, só usávamos propriedades para armazenar dados. Neste artigo, vamos dar um passo adiante, introduzindo o conceito de estado.

Para simplificar, o objeto state é um objeto JavaScript simples, usado para conter informações sobre um componente. O state do componente pode mudar ao longo do tempo, e a qualquer momento que ele mudar, o componente se renderiza novamente.

Assim como o objeto state, as propriedades são objetos JavaScript simples usados para guardar informações sobre o componente. Mas há uma diferença chave entre os adereços e state:

props são passados para o componente (similar aos parâmetros da função) enquanto que state é gerenciado dentro do componente (similar às variáveis declaradas dentro de uma função)

.
Você pode pensar no estado como um instantâneo dos dados obtidos em um dado momento que um aplicativo armazena para controlar o comportamento de um componente. Por exemplo, se a barra lateral de configurações do editor de blocos estiver aberta, uma informação será armazenada em algum lugar no objeto state.

Quando a informação é compartilhada dentro de um único componente, nós a chamamos de local state. Quando a informação é compartilhada entre componentes dentro de um aplicativo, nós a chamamos de Application State.

O estado do aplicativo está intimamente relacionado com o conceito de loja. De acordo com os documentos do Redux:

Uma loja contém toda a árvore de estado do seu aplicativo. A única maneira de mudar o estado dentro dela é enviar uma ação sobre ela.

Assim, Redux armazena um estado do aplicativo em uma única árvore de objetos imutável (ou seja, uma loja). A árvore de objetos só pode ser mudada criando um novo objeto usando ações e redutores.

No WordPress, as lojas são gerenciadas pelo módulo de dados do WordPress.

Modularidade, Pacotes e Lojas de Dados no Gutenberg

O repositório Gutenberg é construído do zero em vários módulos reutilizáveis e independentes que, combinados entre si, constroem a interface de edição. Estes módulos também são chamados de pacotes.

A documentação oficial lista dois tipos diferentes de pacotes:

  • Os pacotes de produção compõem o código de produção que roda no navegador. Existem dois tipos de pacotes de produção no WordPress:
    • Pacotes com folhas de estilo fornecem folhas de estilo para funcionar corretamente.
    • Pacotes com armazenamento de dados definem o armazenamento de dados para lidar com seu estado. Pacotes com armazenamento de dados podem ser usados por plugins e temas de terceiros para recuperar e manipular dados.
  • Os pacotes de desenvolvimento são usados no modo de desenvolvimento. Esses pacotes incluem ferramentas parainting, testes, construção, etc.

Aqui estamos principalmente interessados em pacotes com armazenamento de dados, usados para recuperar e manipular dados.

A loja de dados do WordPress

O módulo de dados do WordPress é construído sobre o Redux e compartilha os três princípios básicos do Redux, embora com algumas diferenças chave.

A documentação oficial fornece a seguinte definição:

O módulo de dados do WordPress serve como um hub para gerenciar o estado do aplicativo tanto para plugins quanto para o próprio WordPress, fornecendo ferramentas para gerenciar dados dentro e entre módulos distintos. Ele é projetado como um padrão modular para organizar e compartilhar dados: simples o suficiente para satisfazer as necessidades de um pequeno plugin, enquanto escalável para atender às exigências de um aplicativo complexa de uma única página.

Por padrão, o Gutenberg registra vários depósitos de dados dentro do estado de aplicativo. Cada uma dessas lojas tem nome e propósito específicos:

Através destas lojas, você poderá acessar um monte inteiro de dados:

  1. Dados relacionados ao artigo atual, tais como título do artigo, trecho, categorias e tags, blocos, etc.
  2. Dados relacionados à interface do usuário, ou seja, se uma alternância estiver ativada ou desativada.
  3. Dados relacionados a toda a instalação do WordPress, tais como taxonomias registradas, tipos de artigos, título do blog, autores, etc.

Estas lojas vivem no objeto global wp. Para acessar o estado de uma loja, você vai usar a função select.

Para ver como funciona, crie um novo artigo ou página e abra o inspetor do seu navegador. Encontre o console e digite a seguinte linha de código:

wp.data.select("core")

O resultado será um objeto incluindo uma lista de funções que você pode usar para obter dados do armazenamento de dados core. Estas funções são chamadas de selectors e funcionam como interfaces para acessar valores de estado.

O objeto central de armazenamento de dados WordPress
O objeto central de armazenamento de dados WordPress

O armazenamento de dados do WordPress inclui informações sobre o WordPress em geral e os seletores são a maneira de você obter essas informações. Por exemplo, getCurrentUser() retorna detalhes para o usuário atual:

wp.data.select("core").getCurrentUser()
Inspecionando a resposta getCurrentUser
Inspecionando a resposta getCurrentUser

Outro seletor que você pode usar para recuperar os detalhes do usuário no data store é getUsers() :

wp.data.select("core").getUsers()

A imagem a seguir mostra o objeto de resposta:

Inspecionando a resposta getUsers
Inspecting getUsers response

Para obter detalhes para um único usuário, você pode apenas digitar a seguinte linha:

wp.data.select("core").getUsers()[0]

Usando o mesmo seletor, você também pode recuperar usuários do site com a função author atribuída:

wp.data.select( 'core' ).getUsers({ who: 'authors' })

Você também pode recuperar as taxonomias registradas:

wp.data.select("core").getTaxonomies()
Inspecionando a resposta getTaxonomies.
Inspecionando a resposta getTaxonomies.

Uma lista dos tipos de correio registrado:

wp.data.select("core").getPostTypes()

Ou uma lista de plugins:

wp.data.select("core").getPlugins()

Agora vamos tentar acessar um armazenamento de dados diferente. Para fazer isso, você ainda vai usar a função select, mas fornecendo um espaço de nomes diferente. Vamos tentar o seguinte:

wp.data.select("core/edit-post")

Agora você terá o seguinte objeto de resposta.

Acesso aos dados da IU do Editor
Acesso aos dados da IU do Editor

Se você quiser saber se as configurações da barra lateral estão abertas ou não, você usaria o seletor isEditorSidebarOpened:

wp.data.select("core/edit-post").isEditorSidebarOpened()

Esta função retorna true se a barra lateral estiver aberta:

A barra lateral está aberta.
A barra lateral está aberta.

Como acessar os dados dos artigos

Agora você deve ter um entendimento básico de como acessar os dados. Agora vamos dar uma olhada mais de perto em um seletor específico, a função getEntityRecords , que é o seletor que dá acesso aos dados do artigo.

No editor de blocos, clique com o botão direito do mouse e selecione Inspect. Na aba Console, copie e cole a seguinte linha:

wp.data.select("core").getEntityRecords('postType', 'post')

Isto envia uma solicitação para a API Restante e retorna um array de registros correspondentes aos últimos artigos publicados no blog.

getEntityRecords retorna uma lista de postagens.
getEntityRecords retorna uma lista de postagens

getEntityRecords aceita três parâmetros:

  • kind string: Tipo de entidade (i.e. postType).
  • name string: Nome da entidade (i.e. post).
  • query ?Object: Termos opcionais consulta (i.e. {author: 0}).

Você pode construir pedidos mais específicos usando um objeto de argumentos.

Por exemplo, você pode decidir que a resposta deve conter apenas mensagens em uma categoria específica:

wp.data.select("core").getEntityRecords('postType', 'post', {categories: 3})

Você também pode solicitar apenas artigos de um determinado autor:

wp.data.select("core").getEntityRecords('postType', 'post', {author: 2})

Se você clicar em qualquer um dos registros devolvidos por getEntityRecords, você receberá uma lista de propriedades para o registro selecionado:

Um exemplo de solicitação de API com getEntityRecords.
Um exemplo de solicitação de API com getEntityRecords

Se você quiser que a resposta inclua a imagem em destaque, você precisará adicionar um argumento adicional ao seu pedido anterior:

wp.data.select("core").getEntityRecords('postType', 'post', {author: 2, _embed: true})
Detalhes da imagem em destaque na resposta do getEntityRecords.
Detalhes da imagem em destaque na resposta do getEntityRecords

Agora você deve ter um melhor entendimento de como acessar o datastore do WordPress e recuperar os detalhes do post. Para uma visão mais próxima no seletor getEntityRecords, veja também Solicitação de dados no Gutenberg com getEntityRecords.

Como criar um bloco dinâmico: Um exemplo de projeto

Após nossa longa premissa teórica, podemos passar à prática e criar um bloco dinâmico usando as ferramentas que introduzimos em nosso tutorial anterior de desenvolvimento de blocos.

Nesse artigo, nós discutimos:

  1. Como Configurar um Ambiente de Desenvolvimento WordPress
  2. O que é um Block Scaffolding
  3. Como construir um bloco estático no Gutenberg

É por isso que não vamos cobrir esses tópicos em profundidade no presente artigo, mas sinta-se à vontade para consultar nosso guia anterior para qualquer informação adicional, ou apenas para um refrescamento.

Configure um ambiente de desenvolvimento JavaScript

Vamos começar por criar um ambiente de desenvolvimento JavaScript.

Instale ou atualize o Node.js

Primeiro, instale ou atualize o Node.js. Uma vez terminado, inicie sua ferramenta de linha de comando e execute o seguinte comando:

node -v

Você deve ver a versão do seu Node.

Configure o seu ambiente de desenvolvimento

A seguir, você vai precisar de um ambiente de desenvolvimento para WordPress. Para nossos exemplos, usamos DevKinsta, nossa ferramenta de desenvolvimento WordPress gratuita que permite a você lançar um site WordPress local em pouco tempo.

Criando um site personalizado no DevKinsta
Criando um site personalizado no DevKinsta

Mas você ainda está livre para escolher qualquer ambiente de desenvolvimento local WordPress que você goste, como MAMP ou XAMPP, ou mesmo a solução oficial wp-env.

Se você estiver usando DevKinsta, clique em New WordPress Site ou em Custom Site, preencha os campos do formulário e clique em Create site.

O processo de instalação leva um ou dois minutos. Quando estiver completo, lance seu site local de desenvolvimento WordPress.

Tela de informação do site no DevKinsta.
Tela de informação do site no DevKinsta.

Configure o seu plugin de bloco

O que você precisa agora é de um plugin de bloco de partida. Para evitar todo o incômodo de uma configuração manual, a equipe central de desenvolvedores do WordPress lançou a ferramenta @wordpress/create-block, que é a ferramenta oficial de configuração zero para a criação de blocos Gutenberg.

Abordamos @wordpress/create-block em profundidade em nosso artigo anterior, então aqui podemos começar o set-up imediatamente.

Em sua ferramenta de linha de comando, navegue para a pasta /wp-content/plugins:

Novo terminal na pasta do Mac OS.
Novo terminal na pasta do Mac OS.

Uma vez lá, execute o seguinte comando:

npx @wordpress/create-block

Agora você está pronto para instalar o pacote @wordpress/create-block:

Instalando o pacote @wordpress/create-block.
Instalando o pacote @wordpress/create-block

Para confirmar, digite y e pressione Enter.

Isto gera os arquivos PHP, SCSS e JS do plugin em modo interativo.

Abaixo estão os detalhes que estaremos usando em nosso exemplo. Sinta-se à vontade para mudar esses detalhes de acordo com suas preferências:


Uma vez que você apertar o enter, ele irá fazer o download e configurar o plugin.

Instalando o plugin do bloco.
Instalando o plugin do bloco

O processo pode demorar alguns minutos. Quando estiver completo, você deve ver a seguinte tela:

Bloqueio bootstrapped na pasta do plugin.
Bloqueio bootstrapped na pasta do plugin

Você verá uma lista dos comandos que você pode executar de dentro do diretório de plugins:

  • $ npm start – Comece a construção para desenvolvimento.
  • $ npm run build – Construa o código para a produção.
  • $ npm run format – Formatar os arquivos.
  • $ npm run lint:css – Arquivos Lint CSS.
  • $ npm run lint:js – Arquivos JavaScript do Lint.
  • $ npm run packages-update – Atualize os pacotes do WordPress para a versão mais recente.

Ok, agora vá para o diretório de plugins com o seguinte comando:

cd author-plugin

E comece a construir seu desenvolvimento:

npm start

Em seguida, navegue para a tela Plugins no seu painel do WordPress e ative o plugin Author box:

O plugin Author box está listado na tela Plugins.
O plugin Author box está listado na tela Plugins

Agora você pode verificar se o plugin está funcionando corretamente. Crie um novo artigo e comece a digitar / para lançar o inseridor rápido:

O item de bloco no inseridor rápido.
O item de bloco no inseridor rápido

Você também encontrará o bloco Author box na categoria Widgets na caixa de inserção de blocos. Selecione o bloco para adicioná-lo à tela do editor:

O Inseridor de Blocos do WordPress.
O Inseridor de Blocos do WordPress

Você está acabado. Agora salve o artigo e visualize a página para verificar se o bloco é exibido corretamente.

O Andaime de Bloco

Nós cobrimos o andaime de bloco em nosso posto anterior. Então, aqui nós só vamos fornecer uma rápida visão geral dos arquivos que vamos modificar para nossos exemplos.

A Pasta de Raiz
A pasta raiz é onde você encontrará o arquivo PHP principal e várias subpastas.

author-plugin.php
Por padrão, o pacote @wordpress/create-block fornece o seguinte arquivo PHP:

/**
 * Plugin Name:       Author box
 * Description:       An example block for Kinsta readers
 * Requires at least: 5.8
 * Requires PHP:      7.0
 * Version:           0.1.0
 * Author:            Carlo
 * License:           GPL-2.0-or-later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       author-plugin
 *
 * @package           author-box
 */

/**
 * 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/reference/functions/register_block_type/
 */
function author_box_author_plugin_block_init() {
	register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'author_box_author_plugin_block_init' );

No cabeçalho, você vai notar os detalhes que inserimos na configuração.

Com blocos estáticos, a maior parte do tempo você estará trabalhando nos arquivos JavaScript localizados na pasta src. Com blocos dinâmicos, você escreverá o código PHP para exibir o conteúdo do bloco no front end.

A Pasta src
A pasta src é a sua pasta de desenvolvimento. Aqui você encontrará os seguintes arquivos:

  • block.json
  • index.js
  • edit.js
  • save.js
  • editor.scss
  • style.scss

block.json
O block.json é o seu arquivo de metadados. @wordpress/create-block gera o seguinte arquivo block.json:

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 2,
	"name": "author-box/author-plugin",
	"version": "0.1.0",
	"title": "Author box",
	"category": "widgets",
	"icon": "businessperson",
	"description": "An example block for Kinsta readers",
	"supports": {
		"html": false
	},
	"textdomain": "author-plugin",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css"
}

Para uma visão mais próxima no arquivo block.json em geral, por favor consulte o nosso artigo anterior no blog.

index.js
O arquivo index.js é onde você registra o tipo de bloco no cliente:

import { registerBlockType } from '@wordpress/blocks';

import './style.scss';

import Edit from './edit';
import save from './save';

registerBlockType('author-box/author-plugin', {
	edit: Edit,
	save,
});

edit.js
O arquivo edit.js é onde você irá construir a interface do bloco renderizado no editor:

import { __ } from '@wordpress/i18n';

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

import './editor.scss';

export default function Edit() {
	return (
		<p {...useBlockProps()}>
			{__('Author box – hello from the editor!', 'author-plugin')}
		</p>
	);
}

save.js
O arquivo save.js contém o script que constrói o conteúdo do bloco a ser salvo no banco de dados. Não vamos usar este arquivo neste tutorial:

import { __ } from '@wordpress/i18n';

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

export default function save() {
	return (
		<p {...useBlockProps.save()}>
			{__('Author box – hello from the saved content!', 'author-plugin')}
		</p>
	);
}

Construindo o bloco para render no editor

Abra seu projeto no Visual Studio Code ou em qualquer editor de código que você goste.

Se você estiver usando Visual Studio Code, vá para Terminal -> New Terminal. Isto irá lançar uma janela de terminal na pasta raiz do seu projeto.

No terminal (ou em sua ferramenta de linha de comando favorita), digite o seguinte comando:

npm start

Agora você está rodando o ambiente do nó no modo de desenvolvimento.

O projeto de plugin de bloco no Visual Studio Code.
O projeto de plugin de bloco no Visual Studio Code.

A partir daqui você estará seguindo dois caminhos diferentes. Para renderizar o bloco no editor, você vai trabalhar no arquivo edit.js. Para renderizar o bloco no front-end, você precisará escrever o código PHP no arquivo principal do plugin.

Agora arregaça suas mangas porque a codificação começa:

[note type=”info”]Neste artigo, nós fornecemos apenas trechos de código. O código completo está disponível em Gist[/notice]

Registrando o bloco no servidor

Primeiro, você tem que registrar o bloco no servidor e escrever o código PHP para recuperar os dados do banco de dados.

No arquivo author-plugin.php, você precisará passar um segundo argumento para a função register_block_type:

function author_box_author_plugin_block_init() {
	register_block_type( __DIR__ . '/build', array(
		'render_callback' => 'author_box_author_plugin_render_author_content'
	) );
}
add_action( 'init', 'author_box_author_plugin_block_init' );

O segundo argumento é uma série de argumentos para registrar um tipo de bloco (veja a lista completa de argumentos disponíveis aqui). No código acima, fornecemos apenas render_callback, que determina a função de retorno de chamada que torna o bloco na tela.

A seguir, você irá declarar a função:

function author_box_author_plugin_render_author_content() {
	return 'Hello World!';
}

Salve o arquivo, crie um novo artigo ou página e adicione o bloco Author Box à tela do editor.

O inseridor de blocos WordPress.
O inseridor de blocos WordPress.

O editor de blocos ainda está mostrando o bloco inicial, pois nós ainda não mudamos o arquivo edit.js.

Mas se você visualizar o artigo no frontend, você verá que o conteúdo original do bloco foi agora substituído pela string “Hello World”.

Agora, como o HTML renderizado no frontend é gerado pelo arquivo PHP, não haverá necessidade da função save para retornar nada. Então vamos direto para o arquivo save.js e mudar o código como mostrado abaixo:

export default function save() {
	return null;
}

Definindo atributos de bloco

Agora você precisa de um lugar para armazenar as configurações do usuário. Por exemplo, o número de itens de artigos a serem recuperados do banco de dados, se você deve exibir ou não um campo especificado, etc. Para fazer isso, você vai definir um número de attributes no arquivo block.json.

Por exemplo, você poderia dar ao usuário a capacidade de determinar o número de postagens a serem incluídas no bloco, a opção de exibir imagem em destaque, data, trecho, e/ou esconder/mostrar a foto do perfil do autor.

Aqui está a lista completa de atributos que vamos usar para construir nosso bloco de exemplo:

{
	...
	"attributes": {
		"numberOfItems": {
			"type": "number",
			"default": 3
		},
		"columns": {
			"type": "number",
			"default": 1
		},
		"displayDate": {
			"type": "boolean",
			"default": true
		},
		"displayExcerpt": {
			"type": "boolean",
			"default": true
		},
		"displayThumbnail": {
			"type": "boolean",
			"default": true
		},
		"displayAuthorInfo": {
			"type": "boolean",
			"default": true
		},
		"showAvatar": {
			"type": "boolean",
			"default": true
		}, 
		"avatarSize": {
			"type": "number",
			"default": 48
		},
		"showBio": {
			"type": "boolean",
			"default": true
		}
	}
}

Construindo o bloco para ser renderizado no editor

O seletor getEntityRecords está incluído no pacote @wordpress/data. Para usá-lo, você precisará importar a hook useSelect desse pacote em seu arquivo edit.js:

import { useSelect } from '@wordpress/data';

A seguir, adicione o seguinte código à função Edit():

const posts = useSelect( ( select ) => {
	return select( 'core' ).getEntityRecords( 'postType', 'post', {
		'per_page': 3
	});
});

No código acima, codificamos o número de artigos de forma rígida. Mas você pode querer dar aos usuários a capacidade de definir um número diferente de mensagens. Você pode usar um atributo para isso.

Em seu block.json você deve ter definido um atributo numberOfItems. Você pode usá-lo em sua função Edit, como mostrado abaixo:

export default function Edit( { attributes } ) {

	const { numberOfItems } = attributes;

	const posts = useSelect( ( select ) => {
		return select( 'core' ).getEntityRecords( 'postType', 'post', {
			'per_page': numberOfItems
		});
	});

	console.log( posts );

	return (
		...
	);
}

Você ainda não verá os artigos na tela, mas execute um console.log e veja o que acontece no console do inspetor do seu navegador:

O resultado no console do navegador.
O resultado no console do navegador.

useSelect pode levar dois argumentos: uma ligação de retorno em linha e uma série de dependências. Ambos retornam uma versão memorizada da callback que só muda quando uma das dependências muda.

Então, a fim de recuperar artigos em cada mudança de atributo numberOfItems, você tem que mudar a função Edit como mostrado abaixo:

export default function Edit( { attributes } ) {

	const { numberOfItems } = attributes;

	const posts = useSelect(
		( select ) => {
			return select( 'core' ).getEntityRecords( 'postType', 'post', {
				'per_page': numberOfItems
			});
		}, 
		[ numberOfItems ]
	);

	console.log(posts);

	return (
		...
	);
}

A seguir você tem que renderizar sua lista de artigos. Para fazer isso, você pode usar o método embutido do JavaScript map:

export default function Edit( { attributes } ) {

	const { numberOfItems } = attributes;

	const posts = useSelect(
		( select ) => {
			return select( 'core' ).getEntityRecords( 'postType', 'post', {
				'per_page': numberOfItems
			});
		},
		[ numberOfItems ]
	);

	console.log(posts);
	
	return (
		<div { ...useBlockProps() }>
			<ul>
				{ posts && posts.map( ( post ) => {
					return (
						<li key={ post.id }>
							<h5>
								<a href={ post.link }>
									{ 
										post.title.rendered ? 
										post.title.rendered :
										__( 'Default title', 'author-plugin' )
									}
								</a>
							</h5>
						</li>
					)
				})}
			</ul>
		</div>
	);
}

Primeiro, ele verifica se você tem pelo menos um artigo na matriz, depois executa o loop.

Note que, como estamos usando o método map com um componente React, também estamos usando um atributo key para atribuir o ID do artigo ao item da lista atual.

post.link e post.title.rendered tornam a URL e o título do artigo respectivamente.

A imagem abaixo mostra a lista completa das propriedades do objeto post.

O objeto Post.
O objeto Post.

O código acima é apenas um exemplo básico de uso do getEntityRecords. Agora é hora de colocar nosso conhecimento em prática.

Digamos que você queira impedir que seu bloco renderize tags HTML que o usuário possa ter adicionado ao título do post. O WordPress fornece um componente RawHTML para isso.

Primeiro, você vai importar o componente do pacote @wordpress/elemento:

import { RawHTML } from '@wordpress/element';

Em seguida, você inclui  o título do artigo dentro do elemento RawHTML:

<div { ...useBlockProps() }>
	<ul>
		{ posts && posts.map((post) => {
			return (
				<li key={ post.id }>
					<h5>
						<a href={ post.link }>
							{ post.title.rendered ? (
								<RawHTML>
									{ post.title.rendered }
								</RawHTML>
							) : (
								__( 'Default title', 'author-plugin' )
							)}
						</a>
					</h5>
				</li>
			)
		})}
	</ul>
</div>

E é isso aí. Agora adicione uma tag HTML ao título do seu artigo e salve o post. Depois teste seu código com e sem RawHTML e veja como o conteúdo do seu bloco muda na tela.

Adicionando data

O WordPress fornece uma série de funções JavaScript para gerenciar e formatar datas. Para usar essas funções você precisa primeiro importá-las do pacote @wordpress/date em seu arquivo edit.js:

import { dateI18n, format, __experimentalGetSettings } from '@wordpress/date';
  • dateI18n: Formatar uma data, traduzindo-a para o locale do site.
  • format: Formatar uma data.
  • __experimentalGetSettings: Exibir a data no formato definido nas configurações gerais do WordPress.

Essas funções não estão documentadas, mas você encontrará exemplos úteis no código fonte de vários blocos. Veja, por exemplo, os últimos artigos e arquivos edit.js pós-data.

Agora adicione o atributo displayDate:

const { numberOfItems, displayDate } = attributes;

Então adicione o seguinte código dentro do elemento <li>:

{ 
	displayDate && (
		<time
			className='wp-block-author-box-author-plugin__post-date'
			dateTime={ format( 'c', post.date_gmt ) }
		>
			{ dateI18n(
				__experimentalGetSettings().formats.date, 
				post.date_gmt
			)}
		</time>
	) 
}

O que acontece aqui?

Adicionando trecho

Agora deve ser fácil adicionar o trecho do post. Primeiro, dê uma olhada na propriedade excerpt no inspetor do navegador. Você verá que o conteúdo real é armazenado em excerpt.rendered.

Inspecionando o trecho do artigo no Chrome DevTools.
Inspecionando o trecho do artigo no Chrome DevTools

A seguir, adicione o atributo displayExcerpt ao objeto attributes:

const { numberOfItems, displayDate, displayExcerpt } = attributes;

Então adicione o seguinte código antes da tag de fechamento </li> na função Edit:

{
	displayExcerpt &&
	post.excerpt.rendered && (
		<p>
			<RawHTML>
				{ post.excerpt.rendered }
			</RawHTML>
		</p>
	)
}

Se você não está familiarizado com JavaScript, aqui e acima usamos a Short Circuit Evaluation, onde, se todas as condições forem verdadeiras, então o valor do último operando é retornado (leia mais em Inline If with Logical && Operator e Logical AND (&&)).

Finalmente, você pode testar seu código novamente. Mude o valor do atributo no arquivo block.json e veja o que acontece no editor.

Adicionando imagem em destaque

Agora você precisa adicionar o código que renderiza as imagens em destaque. Comece a adicionar o atributo displayThumbnail em attributes:

const { 
	numberOfItems, 
	displayDate, 
	displayExcerpt, 
	displayThumbnail 
} = attributes;

Agora você precisa descobrir onde a imagem em destaque é armazenada. Como mencionamos acima, para obter a imagem em destaque, você precisa adicionar um novo argumento _embed à sua consulta. De volta ao seu código, altere os argumentos da consulta da seguinte forma:

const posts = useSelect(
	( select ) => {
		return select( 'core' ).getEntityRecords( 'postType', 'post', {
			'per_page': numberOfItems,
			'_embed': true
		});
	},
	[ numberOfItems ]
);

Aqui nós simplesmente adicionamos '_embed': true ao conjunto de argumentos. Isto fornece um objeto post contendo a propriedade _embedded, que fornece os detalhes da imagem que você precisa para despachar as imagens em destaque.

Agora você deve saber onde encontrar os detalhes da imagem.

Detalhes da imagem em destaque na resposta do getEntityRecords.
Detalhes da imagem em destaque na resposta do getEntityRecords

Você só precisa adicionar o código que renderiza a imagem na tela:

{
	displayThumbnail && 
	post._embedded && 
	post._embedded['wp:featuredmedia'] &&
	post._embedded['wp:featuredmedia'][0] &&
	<img 
	className='wp-block-author-box-author-plugin__post-thumbnail'
		src={ post._embedded['wp:featuredmedia'][0].media_details.sizes.medium.source_url }
		alt={ post._embedded['wp:featuredmedia'][0].alt_text }
	/>
}

Salve o arquivo, mude para o editor de blocos e verifique se a imagem é exibida corretamente quando o atributo displayThumbnail estiver configurado para true.

Uma lista de artigos com imagem, data e trecho em destaque.
Uma lista de artigos com imagem, data e trecho em destaque

Adicionando controles na barra lateral

Até agora nós temos usado os valores padrão de atributos definidos no block.json. Mas pelo nosso artigo anterior sabemos que podemos definir manipuladores de eventos para dar aos usuários a habilidade de atribuir valores personalizados a cada atributo.

Para fazer isso, você adicionará um conjunto de controles à barra lateral de configurações do bloco. Em edit.js, importe os seguintes componentes dos pacotes correspondentes:

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

import {
	PanelBody,
	PanelRow,
	QueryControls,
	ToggleControl,
	RangeControl
} from '@wordpress/components';
  • InspectorControls: Contém configurações da barra lateral que afetam o bloco inteiro (veja no GitHub)
  • PanelBody: Adiciona um recipiente dobrável à barra lateral de configurações (ver em GitHub)
  • PanelRow: Produz um recipiente genérico para controles da barra lateral (veja em GitHub)
  • QueryControls: Fornece controles de configuração para construir uma consulta (veja no GitHub)
  • ToggleControl: Fornece um botão de alternância para que os usuários habilitem/desabilitem uma opção específica (veja no GitHub)
  • RangeControl: É usado para fazer seleções a partir de uma gama de valores incrementais (ver no GitHub)

A seguir, você precisa atualizar a função Edit para usar os controles agora disponíveis. Primeiro, modifique a função Edit como se segue:

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

	const { 
		numberOfItems, 
		columns, 
		displayExcerpt, 
		displayDate, 
		displayThumbnail
	} = attributes;

	const posts = useSelect(
		( select ) => {
			return select( 'core' ).getEntityRecords( 'postType', 'post', {
				'per_page': numberOfItems,
				'_embed': true
			});
		},
		[ numberOfItems ]
	);
	...
}

Note que a propriedade setAttributes passou para a função Edit.

Agora você pode adicionar os elementos correspondentes ao seu código JSX:

return (
	<>
		<InspectorControls>
			<PanelBody title={ __( 'Content Settings', 'author-plugin' ) }>
				<PanelRow>
					<QueryControls 
						numberOfItems={ numberOfItems }
						onNumberOfItemsChange={ ( value ) =>
							setAttributes( { numberOfItems: value } )
						}
						minItems={ 1 }
						maxItems={ 10 }
					/>
				</PanelRow>
				<PanelRow>
					<RangeControl
						label={ __( 'Number of Columns', 'author-plugin' ) }
						value={ columns }
						onChange={ ( value ) =>
							setAttributes( { columns: value } )
						}
						min={ 1 }
						max={ 4 }
						required
					/>
				</PanelRow>
				<PanelRow>
					<ToggleControl
						label={ __( 'Show Featured Image', 'author-plugin' ) }
						checked={ displayThumbnail }
						onChange={ () =>
							setAttributes( { displayThumbnail: ! displayThumbnail } )
						}
					/>
				</PanelRow>
				<PanelRow>
					<ToggleControl
						label={ __( 'Show Date', 'author-plugin' ) }
						checked={ displayDate }
						onChange={ () =>
							setAttributes( { displayDate: ! displayDate } )
						}
					/>
				</PanelRow>
				<PanelRow>
					<ToggleControl
						label={ __( 'Display Excerpt', 'author-plugin' ) }
						checked={ displayExcerpt }
						onChange={ () =>
							setAttributes( { displayExcerpt: ! displayExcerpt } )
						}
					/>
				</PanelRow>
			</PanelBody>
		</InspectorControls>
		<div { ...useBlockProps() }>
			...
		</div>
	</>
);

Uau, isso é muito código, não é? Mas é muito fácil de entender.

Os atributos dos elementos que mais merecem sua atenção aqui são onNumberOfItemsChange em QueryControls e onChange em RangeControl e ToggleControl. Esses atributos definem os manipuladores de eventos necessários para que o usuário possa personalizar a aparência e/ou comportamento de um bloco.

Você também notará que usamos as tags <> e </>, que são a breve sintaxe para declarar fragmentos de React.

Agora, salve seu arquivo, salte para o editor e atualize a página:

Configurações de blocos.
Configurações de blocos.

Está tudo aí dentro? Então vamos seguir em frente e adicionar os detalhes do autor do artigo.

Encontrando o autor do artigo

Como mencionamos acima, nosso bloco mostrará uma lista de artigos escritos pelo mesmo autor que o artigo atual.

Para obter o ID do autor do artigo, você importará o seletor getCurrentPostAttribute do datastore core/editor:

wp.data.select( 'core/editor' ).getCurrentPostAttribute( 'author' )

getCurrentPostAttribute retorna um valor de atributo para o artigo salvo.

Uma vez obtido o ID do autor, você pode alterar a consulta como mostrado abaixo:

const posts = useSelect(
	( select ) => {

		const _authorId = select( 'core/editor' ).getCurrentPostAttribute( 'author' );
	
		return select( 'core' ).getEntityRecords( 'postType', 'post', {
			'author': _authorId,
			'per_page': numberOfItems,
			'_embed': true
		});
	},
	[ numberOfItems ]
);

Com este código, você receberá uma lista n de artigos do mesmo autor que o artigo atual.

Agora que você tem a identificação do autor, você também pode usá-la para buscar dados adicionais no banco de dados.

Exibindo detalhes do autor

Como nós não temos nenhuma documentação disponível, nós usamos o código do bloco central Post Author como referência.

Para exibir os detalhes do autor, você primeiro precisa importar uma nova dependência:

import { forEach } from 'lodash';

Então, na função Edit, atualize o objeto attributes da seguinte forma:

const { 
	numberOfItems, 
	columns, 
	displayExcerpt, 
	displayDate, 
	displayThumbnail, 
	displayAuthorInfo, 
	showAvatar, 
	avatarSize, 
	showBio 
} = attributes;

Uma vez feito, você irá editar o código visto na seção anterior para recuperar os detalhes do autor:

const { authorDetails, posts } = useSelect(
	( select ) => {

		const _authorId = select( 'core/editor' ).getCurrentPostAttribute( 'author' );

		const authorDetails = _authorId ? select( 'core' ).getUser( _authorId ) : null;
	
		const posts = select( 'core' ).getEntityRecords( 'postType', 'post', {
			'author': _authorId,
			'per_page': numberOfItems,
			'_embed': true
		});

		return { 
			authorDetails: authorDetails,
			posts: posts
		};
	},
	[ numberOfItems ]
);

Note que nós usamos o seletorgetUser para obter os detalhes do autor.

A seguir, você pode querer obter o avatar do autor. O código abaixo constrói um conjunto de itens que armazenam URLs e tamanhos de avatares:

const avatarSizes = [];
if ( authorDetails ) {
	forEach( authorDetails.avatar_urls, ( url, size ) => {
		avatarSizes.push( {
			value: size,
			label: `${ size } x ${ size }`,
		} );
	} );
}

Então você adicionará os painéis e controles da barra lateral para permitir que os usuários personalizem a área do autor no bloco:

return (
	<>
		<InspectorControls>
			<PanelBody title={ __( 'Author Info', 'author-plugin' ) }>
				<PanelRow>
					<ToggleControl
						label={ __( 'Display Author Info', 'author-plugin' ) }
						checked={ displayAuthorInfo }
						onChange={ () =>
							setAttributes( { displayAuthorInfo: ! displayAuthorInfo } )
						}
					/>
				</PanelRow>
				{ displayAuthorInfo && (
					<>
						<PanelRow>
							<ToggleControl
								label={ __( 'Show avatar' ) }
								checked={ showAvatar }
								onChange={ () =>
									setAttributes( { showAvatar: ! showAvatar } )
								}
							/>
							{ showAvatar && (
								<SelectControl
									label={ __( 'Avatar size' ) }
									value={ avatarSize }
									options={ avatarSizes }
									onChange={ ( size ) => {
										setAttributes( {
											avatarSize: Number( size ),
										} );
									} }
								/>
							) }
						</PanelRow>
						<PanelRow>
							<ToggleControl
								label={ __( 'Show Bio', 'author-plugin' ) }
								checked={ showBio }
								onChange={ () =>
									setAttributes( { showBio: ! showBio } )
								}
							/>
						</PanelRow>
					</>
				) }
			</PanelBody>
			...
		</InspectorControls>
		...
	</>
);

A imagem abaixo mostra as configurações atualizadas da barra lateral:

O painel de configurações de Informações do Autor.
O painel de configurações de Informações do Autor

Finalmente, você pode adicionar a seção do autor ao seu bloco:

return (
	<>
		<InspectorControls>
		...
		</InspectorControls>

		<div { ...useBlockProps() }>
			{ displayAuthorInfo  && authorDetails && (
				<div className="wp-block-author-box-author-plugin__author">
					{ showAvatar && (
						<div className="wp-block-author-box-author-plugin__avatar">
							<img
								width={ avatarSize }
								src={
									authorDetails.avatar_urls[
										avatarSize
									]
								}
								alt={ authorDetails.name }
							/>
						</div>
					) }
					<div className='wp-block-author-box-author-plugin__author-content'>
						<p className='wp-block-author-box-author-plugin__name'>
							{ authorDetails.name }
						</p>
						{ showBio &&
							// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
							authorDetails?.description &&
							authorDetails.description.length > 0 && (
							<p className='wp-block-author-box-author-plugin__description'>{ authorDetails.description }</p>
						) }
					</div>
				</div>
			)}
			<ul>
			...
			</ul>
		</div>
	</>
);

A imagem a seguir mostra como ela se torna na tela.

Seção de detalhes do autor e configurações de informações.
Seção de detalhes do autor e configurações de informações

Agora salve seu arquivo edit.js e execute seus testes. Seu bloco deve incluir diferentes elementos, dependendo das configurações do bloco.

Detalhes do autor não mostrando a biografia do autor.
Detalhes do autor não mostrando a biografia do autor.

Uma última coisa ainda está faltando: o número de colunas para exibir artigos.

Alterando o número de colunas

Para dar ao usuário a habilidade de mostrar prévias de artigos em colunas, nós definimos o atributo columns no arquivo block.json. Nós também incluímos um atributo columns no script e criamos um controle de configurações para permitir que os usuários mudem o número de colunas, embora esta mudança não tenha efeito no momento.

No código JSX acima você deve ter notado que nós adicionamos classes CSS a vários elementos:

Classes atribuídas aos elementos na seção Autor:

  • wp-block-author-box-author-plugin__author
  • wp-block-author-box-author-plugin__avatar
  • wp-block-author-box-author-plugin__author-content
  • wp-block-author-box-author-plugin__name
  • wp-block-author-box-author-plugin__description

Classes atribuídas aos elementos na seção de conteúdo:

  • wp-block-author-box-author-plugin__post-items
  • wp-block-author-box-author-plugin__post-thumbnail
  • wp-block-author-box-author-plugin__post-title
  • wp-block-author-box-author-plugin__post-date
  • wp-block-author-box-author-plugin__post-excerpt

Uma classe ainda está faltando. O nome desta classe será gerado dinamicamente para refletir o número de colunas definidas pelo usuário.

Volte para o arquivo Edit.js e modifique o elemento ul da seguinte forma:

<ul className={ `wp-block-author-box-author-plugin__post-items columns-${ columns }` }>
	...
</ul>

Nós adicionamos uma nova classe columns-${ columns } de acordo com a sintaxe literal do Template para inserir uma expressão dentro de uma string. Desta forma, o atributo anexado ao elemento ul dependerá das configurações do usuário (por exemplo columns-1, columns-2, etc.).

Agora abra o arquivo style.scss e substitua o código existente com o seguinte:

.wp-block-author-box-author-plugin {
	background-color: #21759b;
	color: #fff;
	padding: .6em;
	ul.wp-block-author-box-author-plugin__post-items {
		padding: 0;
		list-style-type: none;
		display: grid;
		gap: .5em;
		@for $i from 2 through 4 {
			&.columns-#{ $i } {
				grid-template-columns: repeat(#{ $i }, 1fr);
			}
		}
		li {
			list-style: none;
			img.wp-block-author-box-author-plugin__post-thumbnail {
				height: auto;
				max-width: 100%;
			}
		}
		
	}
}
.wp-block-author-box-author-plugin__author {
	display: flex;
    flex-wrap: wrap;
}

.wp-block-author-box-author-plugin__avatar {
	margin-right: 1em;
}

.wp-block-author-box-author-plugin__author-content {
	flex-basis: 0;
    flex-grow: 1;
}

Não iremos a fundo nesse código, estando além do escopo deste artigo. Mas se você quiser mergulhar mais fundo, você pode consultar os seguintes recursos:

O bloco do Autor no editor.
O bloco do Autor no editor.

E isso é tudo para a renderização do bloco no editor.

Construindo o bloco para renderizar na página

Agora que o código que renderiza o bloco no editor está completo, podemos avançar e construir o bloco para renderização no frontend.

Como mencionamos anteriormente, quando se trata de blocos dinâmicos, o arquivo de plugin é responsável por gerar o HTML a ser renderizado no front end.

Então, abra o arquivo principal do seu plugin (author-plugin.php em nosso exemplo).

A primeira coisa a fazer é tornar os atributos do bloco disponíveis para a função PHP do WordPress. Em seu arquivo PHP, altere a definição da função da seguinte forma:

function author_box_author_plugin_render_author_content( $attr ) {
	...
}

Agora você pode usar as funções do WordPress para recuperar e manipular dados. Por exemplo, você pode usar get_posts para recuperar os últimos artigos do blog (leia mais em nosso artigo detallhado sobre a funçãoget_posts ):

function author_box_author_plugin_render_author_content( $attr ) {
	$args = array(
		'numberposts'	=> $attr['numberOfItems'],
	);
	$my_posts = get_posts( $args );
	
	if( ! empty( $my_posts ) ){
		$output = '<ul>';
		foreach ( $my_posts as $p ){
			$output .= '<li><a href="' . esc_url( get_permalink( $p->ID ) ) . '">' 
			. $p->post_title . '</a></li>';
		}
		$output .= '</ul>';
	}
	return $output ?? '<strong>Sorry. No posts matching your criteria!</strong>';
}

A função acima recupera os últimos artigos do blog numberOfItems do seu banco de dados WordPress (por padrão post_type está configurado para post) e retorna um conjunto de objetos $post. Do que itera por cima do array para construir os itens da lista.

Se você inspecionar a saída HTML, você notará que é uma lista simples de postagens, como a mostrada na imagem a seguir:

Uma lista simples de postagens.
Uma lista simples de postagens

Em nosso artigo anterior nós mencionamos que você usará o hook de reação useBlockProps para marcar o elemento de wrapper do bloco em seu código JSX. Você precisará fazer o mesmo em sua função PHP.

O WordPress fornece a funçãoget_block_wrapper_attributes para isso.

Então, mude seu código PHP da seguinte forma:

function author_box_author_plugin_render_author_content( $attr ) {
	$args = array(
		'numberposts'	=> $attr['numberOfItems']
	);
	$my_posts = get_posts( $args );
	
	if( ! empty( $my_posts ) ){
		$output = '<div ' . get_block_wrapper_attributes() . '>';
		$output .= '<ul>';
		foreach ( $my_posts as $p ){
			
			$title = $p->post_title ? $p->post_title : 'Default title';
			$url = esc_url( get_permalink( $p->ID ) );

			$output .= '<li>';
			$output .= '<a href="' . $url . '">' . $title . '</a>';
			$output .= '</li>';
		}
		$output .= '</ul>';
		$output .= '</div>';
	}
	return $output ?? '<strong>Sorry. No posts matching your criteria!</strong>';
}

Agora uma classe wp-block-author-box-author-plugin foi designada para o elemento recipiente e o bloco tem uma cor de fundo diferente.

Então a função get_posts obtém dados WP_Posts e o ciclo foreach constrói os itens da lista (veja também Como exibir dados restituído do get_posts).

Uma lista de artigos com uma classe CSS atribuída.
Uma lista de artigos com uma classe CSS atribuída.

Adicionando imagem em destaque, data e extrato

Em seguida, você precisará adicionar thumbnails, datas e extratos do artigo. No mesmo arquivo, altere seu código PHP como a seguir:

function author_box_author_plugin_render_author_content( $attr ) {
	$args = array(
		'numberposts'	=> $attr['numberOfItems']
	);
	$my_posts = get_posts( $args );
	
	if( ! empty( $my_posts ) ){
		$output = '<div ' . get_block_wrapper_attributes() . '>';
		$output .= '<ul class="wp-block-author-box-author-plugin__post-items columns-">';

		foreach ( $my_posts as $p ){
			
			$title = $p->post_title ? $p->post_title : 'Default title';
			$url = esc_url( get_permalink( $p->ID ) );
			$thumbnail = has_post_thumbnail( $p->ID ) ? get_the_post_thumbnail( $p->ID, 'medium' ) : '';

			$output .= '<li>';
			if( ! empty( $thumbnail ) && $attr['displayThumbnail'] ){
				$output .= $thumbnail;
			}
			$output .= '<h5><a href="' . $url . '">' . $title . '</a></h5>';
			if( $attr['displayDate'] ){
				$output .= '<time datetime="' . esc_attr( get_the_date( 'c', $p ) ) . '">' . esc_html( get_the_date( '', $p ) ) . '</time>';
			}
			if( get_the_excerpt( $p ) && $attr['displayExcerpt'] ){
				$output .= '<p>' . get_the_excerpt( $p ) . '</p>';
			}
			$output .= '</li>';
		}
		$output .= '</ul>';
		$output .= '</div>';
	}
	return $output ?? '<strong>Sorry. No posts matching your criteria!</strong>';
}

O foreach literatiza o loop sobre a matriz $my_posts. A cada iteração, várias condições verificam os valores dos atributos e constroem a saída de acordo.

Agora dê uma olhada na saída na tela:

Uma lista de postagens com imagens em destaque, datas e extratos.
Uma lista de postagens com imagens em destaque, datas e extratos

Agora você pode fazer seus testes. Mude a data, trecho e configurações de miniaturas e verifique como o conteúdo do bloco muda no front-end.

Exibindo artigos nas colunas

Em nosso código JavaScript, nós usamos uma classe columns-${ columns } para exibir prévias de artigos em colunas. Agora nós precisamos fazer o mesmo no PHP.

Para fazer isso, você simplesmente tem que adicionar estas duas linhas de código:

$num_cols = $attr['columns'] > 1 ? strval( $attr['columns'] ) : '1';

$output .= '<ul class="wp-block-author-box-author-plugin__post-items columns-' . $num_cols . '">';

Isto irá anexar uma classe columns-n ao elemento ul contendo as prévias do artigo. Agora o número de colunas exibidas na página deve corresponder ao número de colunas definidas nas configurações do bloco.

Construindo o caixa do autor

Por último, você precisa construir a caixa contendo os detalhes do autor, incluindo avatar, nome e descrição.

Dentro da função chamada de retorno, você precisará adicionar um conjunto de condições para verificar o valor atual de cada atributo:

if( $attr['displayAuthorInfo'] ){
	$output .= '<div class="wp-block-author-box-author-plugin__author">';
	
	if( $attr['showAvatar'] ){
		$output .= '<div class="wp-block-author-box-author-plugin__avatar">' 
			. get_avatar( get_the_author_meta( 'ID' ), $attr['avatarSize'] ) 
			. '</div>';
	}

	$output .= '<div class="wp-block-author-box-author-plugin__author-content">';
	
	$output .= '<div class="wp-block-author-box-author-plugin__name">' 
		. get_the_author_meta( 'display_name' ) 
		. '</div>';

	if( $attr['showBio'] ){
		$output .= '<div class="wp-block-author-box-author-plugin__description">' 
			. get_the_author_meta( 'description' ) 
			. '</div>';
	}

	$output .= '</div>';
	$output .= '</div>';
}

O código é bastante simples. Ele verifica o valor atual de cada atributo, e se ele for true, então ele irá gerar o HTML necessário.

Agora salve seu arquivo PHP e compare o bloco no editor vs. o mesmo bloco no frontend.

Nosso bloco personalizado no editor de blocos.
Nosso bloco personalizado no editor de blocos.

Você encontrará o código completo do bloco de exemplo neste Gist público.

Funcionalidades recomendadas para o desenvolvimento de blocos dinâmicos

Se a leitura deste artigo despertou seus sentimentos e você começou a reconhecer as oportunidades de desenvolvimento profissional que podem surgir da aprendizagem para criar blocos Gutenberg, nosso conselho é continuar explorando e adquirindo novas habilidades nas tecnologias por trás do desenvolvimento de blocos.

Embora ainda falte documentação oficial confiável, apesar de haver excelentes recursos por aí, tanto gratuitos como pagos, nós consultamos enquanto escrevíamos este artigo. Entre os muitos recursos disponíveis, nós recomendamos o seguinte:

Recursos oficiais

Tutoriais recomendados por colaboradores do WordPress Core

Recursos JavaScript, Reage, e Redux

Recursos relacionados da Kinsta

Resumo

Chegamos ao fim desta (segunda) longa jornada através do desenvolvimento do bloco Gutenberg.

Neste artigo, cobrimos alguns tópicos avançados, tais como Estado do aplicativo e Store Redux. Mas esperamos que você tenha agora uma melhor compreensão do desenvolvimento de blocos em geral.

Sim, Node.js, Webpack, Babel, React e Redux são essenciais quando se trata de construir blocos Gutenberg avançados, mas você não precisa ser um ninja React para começar. Aprender como desenvolver blocos de Gutenberg não precisa necessariamente ser complicado. Apenas faça-o com a motivação certa e seguindo o caminho de aprendizado apropriado.

E esperamos que este artigo – e o anterior – forneça a você o mapa certo para encontrar seu caminho e começar a desenvolver o Gutenberg imediatamente.

Até você agora! Você já criou blocos dinâmicos? Você tem algum exemplo para compartilhar conosco? E quais foram os maiores obstáculos em sua experiência? Sinta-se à vontade para deixar um comentário abaixo.

Carlo Daniele Kinsta

Carlo is a passionate lover of webdesign and front-end development. He has been playing with WordPress for more than 20 years, also in collaboration with Italian and European universities and educational institutions. He has written hundreds of articles and guides about WordPress, published both on Italian and international websites, as well as on printed magazines. You can find him on LinkedIn.