Criar bloco personalizado do Gutenberg – Parte 10: Buscando postagens e componentes de ordem superior
Nesta parte final da série de tutoriais de blocos personalizados do Gutenberg, aprenderemos como usar componentes de ordem superior para utilizar os componentes do WordPress para realizar consultas para postagens e outras informações essenciais do WordPress.
Na parte anterior, aprendemos sobre blocos dinâmicos e acabamos implementando a funcionalidade para digitar um ID de postagem e usar PHP para buscar a postagem dinamicamente e renderizá-la no modo frontend e de visualização. Digitar manualmente um ID de postagem não é intuitivo ou fácil de usar. É muito melhor fornecer ao usuário alguma maneira de selecionar ou pesquisar postagens pelo título da postagem e clicar em algo para escolher uma.
Uma parte de resolver isso é bastante fácil; como consultar posts da edit
função do seu bloco. Temos algumas opções para isso, e a melhor opção é usar alguns dos chamados componentes de ordem superior do WordPress. Você também pode usar métodos do navegador Javascript para executar uma chamada AJAX para a API REST do WordPress usando, por exemplo [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
, ou axios. Na verdade, o WordPress fornece sua própria versão de fetch
: apiFetch()
.
A outra parte de resolver isso depende um pouco de você; que é como apresentar a lista ou escolha em nosso bloco. Como você vai apresentar a lista de posts para escolher? Em um select, lista de checkboxes ou radio buttons? Ou deseja oferecer a possibilidade de pesquisar e, assim, implementar uma solução de preenchimento automático ou uma solução de filtro? Você deve permitir a seleção de várias postagens ou apenas uma? Normalmente, você pode resolver isso usando diferentes componentes do WordPress, mas precisa decidir qual solução deseja implementar.
Vamos primeiro aprender um pouco sobre componentes de ordem superior e o módulo de dados do WordPress, antes de vermos como podemos realizar consultas de postagem em nosso bloco.
Módulo WordPress Core Data e componentes de ordem superior
Ao trabalhar com o React, muitas vezes você precisará passar o estado para os componentes filho ou para cima para um componente pai comum para que todos os outros componentes filho tenham acesso a eles. Uma solução para resolver o problema de centralizar o estado de um aplicativo é usando o Redux. Com o Redux você pode construir lojas – que são objetos que guardam o estado e as informações de uma aplicação.
O módulo de dados do WordPress é um hub de diferentes lojas e fornece funções para gerenciar dados entre diferentes módulos. Ele é construído em cima do Redux – mas não o confunda com um Redux para WordPress, pois existem algumas diferenças. Você pode registrar suas próprias lojas no WordPress, ou talvez mais importante, acessar as lojas registradas do WordPress.
Aqui está uma visão geral das lojas disponíveis no módulo de dados do WordPress (provavelmente mudará com o tempo). Todas as lojas do WordPress estão contidas no módulo Core Data. Por exemplo, existem lojas que contêm os dados do editor (core/editor
), avisos (core/notices
), dados do bloco (core/blocks
), informações da viewport (core/viewport
) e por último mas não menos importante a própria loja principal – core
.
Para acessar os dados das lojas, você precisará usar seletores. O WordPress tem um seletor dentro do wp.data
pacote; [select](https://developer.wordpress.org/block-editor/packages/packages-data/#select)()
. Você também pode manipular as lojas com dispatch
, mas isso não é coberto por esta série de tutoriais. Você pode realmente facilmente experimentar o seletor para ver o que está disponível nas lojas do WordPress.
Testando o seletor
Abra o editor Gutenberg no Chrome e abra a ferramenta de depuração do console. Digitar:
wp.data.select('core')
E pressione Enter. Você deve obter um objeto como resposta com todos os seletores (funções) que você pode usar. Como exemplos, você encontrará funções como getMedia
, getTaxonomy
, getAuthors
e assim por diante. O que usaremos para consultar os posts também está lá, mas não tem um nome intuitivo; é chamado getEntityRecords
. No momento algumas dessas funções estão documentadas, mas a maioria não está, infelizmente.
Experimente também outras lojas que não core
, por exemplo:
wp.data.select('core/editor').getBlocks()
Isso retorna todas as informações sobre todos os blocos atualmente em sua postagem. Você pode brincar com isso no depurador do console do Chrome e tentar chamar algumas funções para ver o que você obtém em resposta. Alguns requerem parâmetros e outros não.
Para usar seletores e armazenamentos de acesso, precisamos usá-los em componentes de ordem superior. Componentes de ordem superior são simplesmente um padrão de fazer algo no React. Passamos um componente para uma função (ou componente) que pode adicionar algumas props e, em seguida, retornar um novo componente.
Dentro do módulo de dados do WordPress encontramos [withSelect](https://developer.wordpress.org/block-editor/packages/packages-data/#withSelect)
; um componente de ordem superior que pode ser usado para injetar props usando seletores registrados. Em outras palavras; dentro withSelect
temos acesso ao seletor select()
e podemos usá-lo para realizar chamadas. Os resultados do seletor serão props para o componente para o qual passamos withSelect
. Se você precisar combinar vários componentes de ordem superior, o módulo de dados do WordPress oferece a compose
função, mas isso está fora do escopo deste tutorial. Usaremos apenas um componente de ordem superior; withSelect
.
Isso tem sido muita teoria, então vamos começar a ver alguns códigos e exemplos práticos.
Buscando postagens usando withSelect, select e getEntityRecords
Para resumir o que foi dito acima, precisamos configurar o componente de ordem superior withSelect
para nosso bloco. Dentro disso podemos usar seletores para acessar as lojas do WordPress, que serão props para o componente que passarmos para o withSelect
. Usaremos a core
loja e o seletor getEntityRecords
para consultar as postagens.
A função getEntityRecords
infelizmente não está muito documentada no momento. Mas aprendi que podemos passar postType
como primeiro parâmetro (tipo de entidade) e depois o tipo de postagem como segundo parâmetro (por exemplo, ‘ post
‘ ou ‘ page
‘). O terceiro parâmetro é opcional e pode ser um objeto com argumentos de consulta. Veremos o terceiro parâmetro mais adiante.
Se você seguiu esta série de tutoriais da parte anterior, você teria um bloco personalizado que aceita um ID de postagem digitado manualmente em uma entrada de texto. O bloco usa PHP para renderizar dinamicamente o post no frontend (e no modo de visualização). Vamos remover a exigência de digitar manualmente o ID do post e substituí-lo por algo mais intuitivo. Como mencionado anteriormente, você precisa decidir por si mesmo como apresentar a lista de postagens e a melhor maneira de permitir que o usuário escolha uma postagem. Para simplificar, adicionaremos uma seleção de todos os títulos de postagem para escolher.
Codificando owithSelect
Vamos começar a codificar isso. Primeiro precisamos desestruturar o que precisamos do pacote de dados;
const { withSelect, select } = wp.data;
Então usamos withSelect
na função do nosso bloco edit
e passamos nosso componente de edição; FirstBlockEdit
. Dentro withSelect
desestruturamos select
como parâmetro e usamos o seletor select()
para consultar posts com getEntityRecords
. Retornamos um objeto com uma propriedade que chamamos posts
que contém o resultado da select()
chamada.
Com o código acima nosso componente, FirstBlockEdit
, agora terá uma nova prop; posts
. Tudo o que retornarmos dentro do withSelect
componente de ordem superior estará acessível como adereços para o componente que passarmos (no parêntese no final).
Manipulando as postagens do seletor
Agora podemos entrar em nosso componente FirstBlockEdit
e dar uma olhada no novo arquivo props.posts
. Como nosso componente é um componente baseado em classe, precisamos nos referir a props com this
. Vamos consolá-lo dentro da render()
função em FirstBlockEdit
:
render() {
const { attributes, setAttributes } = this.props;
console.log(this.props.posts);
...
}
Fique de olho no depurador do seu console. Você pode notar que isso será registrado duas vezes; first null
e, algum tempo depois, registra uma série de postagens. Isso ocorre porque a consulta de postagens é feita de forma assíncrona. Nosso componente é renderizado primeiro antes da resposta, momento em que props.posts
é null
. Assim que obtivermos uma resposta, nosso componente será renderizado novamente com o prop preenchido. Você deve sempre se lembrar de acomodar este pequeno período de tempo sem dados em seu código.
Adicionando um select para exibir as postagens
Vamos nos preparar para preencher um select com os posts retornados e para isso usaremos o componente WordPress SelectControl
. O componente SelectControl
aceita um array de escolhas onde cada escolha é um objeto com as propriedades value
e label
.
Se você der uma olhada na resposta do console logado (segunda), você pode ver que obtemos um array de objetos post. Cada postagem contém a maioria das informações da postagem, mas para as opções em uma seleção, estamos interessados apenas no ID da postagem como valor e no título da postagem como rótulo. Então, vamos percorrer o posts
prop e preencher uma variável de matriz que passaremos para SelectControl
. Não se esqueça de lidar com o pequeno período de tempo em que o posts
suporte está null
. Nesse caso, preencheremos o array choice com uma opção que tenha o rótulo “Loading…".
Observe que precisamos nos referir ao título do post como post.title.rendered
. Você pode procurar por si mesmo no console logado posts
e ver como as informações estão estruturadas para cada post.
Depois disso, simplesmente precisamos adicionar um SelectControl
onde quisermos. Ele pode estar dentro do próprio bloco (preferencialmente dentro do código para o modo de edição), ou dentro do Inspector.
Definimos o SelectControl
para se referir ao atributo selectedPostId
que definimos na etapa anterior. Definimos o valor salvo no prop value
e tratamos de atualizá-lo no onChange
prop – assim como fizemos várias vezes antes. Garantimos que um número seja armazenado usando parseInt()
porque selectedPostId
tem o tipo number
. E passamos o array de escolhas gerado no prop options
.
Isso é tudo! Se você seguiu o código da etapa anterior, já deve ter um código que lê o ID do post salvo e o exibe!
Claro que eu recomendo que você implemente a lista e escolha de posts de forma diferente de apenas um simples select. Esta não é uma solução bonita ou fácil de usar, especialmente para sites com muitos posts. Falando em quantidade de posts, você percebeu que o seletor getEntityRecords só retorna no máximo os 10 últimos posts? Esse é o comportamento padrão de getEntityRecords, mas podemos modificar a consulta post passando um terceiro parâmetro.
Modifique a consulta para getEntityRecords
Passando um objeto como terceiro parâmetro para getEntityRecords podemos modificar a consulta post. Como mencionado antes, infelizmente, getEntityRecords
falta a documentação para. Mas lendo por toda a web, reuni uma lista de possíveis argumentos de consulta;
per_page
: defina como um número para limitar o número de postagens. Defina como-1
para buscar o máximo de 100. Padrão10
.exclude
: exclui determinadas postagens da consulta. Defina como um ID de postagem ou uma matriz de números para vários IDs de postagem.parent_exclude
: exclui determinadas postagens principais. Defina como um ID de postagem ou uma matriz de vários IDs de postagem.orderby
: Decida a ordem das postagens. Muito provavelmente você pode usar os mesmos parâmetros que no orderby de WP_Query. Pode ser, por exemplo, ‘menu_order
‘.order
: Ou'asc'
ou ‘desc'
para ordenação ascendente ou descendente.status
: Filtre por status de postagem. Pode ser uma string, uma string com vários status separados por vírgula ou uma matriz de strings de status. Por exemplo['publish', 'draft']
, para consultar posts publicados e redigidos.categories
: Filtre as postagens por determinadas categorias. Forneça um ID de categoria ou uma matriz de IDs de categoria. Acredito que isso funcione apenas para categorias de postagem e não para outras taxonomias personalizadas.tags
: Filtre as postagens por determinadas tags. Forneça um ID de tag ou uma matriz de IDs de tag. Funciona apenas para tags de postagem e não para outras taxonomias personalizadas.search
: Adicione uma consulta de pesquisa (string).
Nota: Esta não é uma lista exaustiva e também está sujeita a alterações!
Vamos modificar nossa consulta. Queremos fazer duas coisas; primeiro queremos buscar todos os posts e não apenas os 10 mais recentes. Para fazer isso, fornecemos -1
para per_page
. Em segundo lugar, queremos excluir a postagem atual da lista de postagens fornecendo o ID da postagem atual para exclude
. Muitas vezes não faz sentido mostrar um atalho de postagem ou visualização da própria postagem atual.
Você pode pensar; espere, como obtemos o ID do post atual? Não se esqueça de que nós, dentro do componente de ordem superior withSelect
e com o select
seletor, podemos acessar todos os principais armazenamentos de dados do WordPress. O ID de postagem atual é uma coisa natural para armazenar em uma das principais lojas do WordPress. Dentro core/editor
encontramos a função getCurrentPostId()
.
Vamos modificar o withSelect
retorno para algo assim:
A mudança acima é bastante auto-explicativa. Geramos um objeto de consulta com as propriedades per_page
e exclude
passamos isso como terceiro parâmetro para getEntityRecords()
. Agora nosso componente props.posts
dentro do FirstBlockEdit
componente deve listar todas as postagens, mas excluir a postagem atual.
Conclusão
Esta postagem conclui a série de tutoriais Como criar blocos personalizados do Gutenberg. A série foi projetada para passar pelo básico do desenvolvimento de seus próprios blocos personalizados, fornecendo a você um ponto de partida para desenvolver seus próprios blocos e mais complexos. Definitivamente, fique de olho em mais tutoriais relacionados ao Gutenberg aqui. Talvez você encontre um tutorial explicando mais especificamente algo que você queria fazer sozinho!