Blog

Como fazer o parsing do conteúdo do Gutenberg para o WordPress headless

Uncategorized

Como fazer o parsing do conteúdo do Gutenberg para o WordPress headless

do conteúdo dos blocos do Gutenberg em um site estático Next.js

Nesta seção, vamos entender como extrair o conteúdo do WordPress em um projeto Next.js e depois converter os blocos do Gutenberg em HTML.

Para começar, vamos criar uma função para obter as postagens do seu site WordPress. Abra o arquivo src/page.js em seu projeto e substitua seu conteúdo pelo seguinte trecho de código:

Gutenberg – o editor padrão para o WordPress. Ele permite criar e formatar conteúdo usando blocos individuais para texto, imagens, vídeos e outros elementos do site através de uma interface de arrastar e soltar. Esse método aumenta a flexibilidade e as capacidades de design do WordPress. Vamos entender como o Gutenberg funciona para o WordPress headless?

Este guia explica como analisar o conteúdo do Gutenberg em HTML usando a REST API do WordPress em um site estático Next.js.

Condições necessárias

Para seguir este guia, você precisará de:

  • Node.js e npm (Node Package Manager) ou yarn, instalados em seu computador
  • Conhecimentos básicos de JavaScript
  • Um site WordPress com várias postagens publicadas

Obtendo conteúdo do Gutenberg usando a REST API

Para obter o conteúdo do Gutenberg usando a REST API, você pode interagir com o seu site WordPress programaticamente e receber o conteúdo estruturado em blocos Gutenberg. Isso é feito através da REST API do WordPress ou do plugin WPGraphQL. Essas ferramentas permitem que você receba o conteúdo do WordPress no formato JSON.

Para habilitar o acesso aos dados JSON através da REST API, você precisa alterar as configurações de permalinks do WordPress de “Padrão” para outra opção. Isso permite o acesso à API através de uma URL estruturada, por exemplo:

https://yourwebsite.com/wp-json/wp/v2

Fazendo solicitações à API neste URL, você pode receber várias informações e executar operações em seu site WordPress. Por exemplo, você pode obter uma lista de postagens enviando uma solicitação GET para:

Isso retornará um objeto JSON contendo informações sobre as postagens em seu site WordPress, incluindo títulos, conteúdo, dados do autor e muito mais.

https://yourwebsite.com/wp-json/wp/v2/posts

Parsing de blocos do Gutenberg em HTML

Ao obter postagens de um site WordPress que usa o editor Gutenberg, o conteúdo armazenado no banco de dados pode ser uma mistura de HTML e metadados JSON para descrever diferentes tipos de blocos, como citações e galerias. Por exemplo:

<!-- wp:quote {"className":"inspirational-quote","style":{"typography":{"fontSize":"large"}}} --><blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>“A jornada de mil milhas começa com um único passo.”</p><cite>Lao Tzu</cite></blockquote><!-- /wp:quote --><!-- wp:gallery {"ids":[34,35],"columns":2,"linkTo":"none","sizeSlug":"medium","className":"custom-gallery"} --><ul class="wp-block-gallery columns-2 is-cropped custom-gallery"><li class="blocks-gallery-item"><figure><img src="https://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="Uma vista deslumbrante das montanhas" class="wp-image-34"/></figure></li><li class="blocks-gallery-item"><figure><img src="https://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Lagoa serena ao amanhecer" class="wp-image-35"/></figure></li></ul><!-- /wp:gallery -->

Este trecho ilustra dois blocos do Gutenberg: uma citação e uma galeria. Cada um deles é complementado com metadados JSON, encapsulados em comentários HTML. Os metadados definem atributos como nomes de classe, estilos e outras configurações relacionadas à visualização do bloco.

Quando você obtém esses blocos via REST API do WordPress ou WPGraphQL, o WordPress os processa, convertendo a combinação de HTML e metadados JSON em elementos HTML totalmente renderizados que você pode injetar diretamente nas páginas da web. O HTML convertido para os blocos acima será assim:

<blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>“A jornada de mil milhas começa com um único passo.”</p><cite>Lao Tzu</cite></blockquote><ul class="wp-block-gallery columns-2 is-cropped custom-gallery">  <li class="blocks-gallery-item"><figure><img loading="lazy" src="https://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="Uma vista deslumbrante das montanhas" class="wp-image-34" sizes="(max-width: 300px) 100vw, 300px" /></figure></li>  <li class="blocks-gallery-item"><figure><img loading="lazy" src="https://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Lagoa serena ao amanhecer" class="wp-image-35" sizes="(max-width: 300px) 100vw, 300px" /></figure></li></ul>

Para desenvolvedores criando aplicativos decoupled ou headless usando frameworks JavaScript, como Next.js, este método oferece uma maneira simples de exibir conteúdo, injetando HTML diretamente na página usando a propriedade dangerouslySetInnerHTML para renderizar a marcação.

Aqui está a sintaxe para usar essa propriedade:

<div dangerouslySetInnerHTML={{ __html: <raw_html_string> }} />

Parsing do conteúdo dos blocos do Gutenberg em um site estático Next.js

Nesta seção, vamos entender como extrair o conteúdo do WordPress em um projeto Next.js e depois converter os blocos do Gutenberg em HTML.

Para começar, vamos criar uma função para obter as postagens do seu site WordPress. Abra o arquivo src/page.js em seu projeto e substitua seu conteúdo pelo seguinte trecho de código:

const getWpPosts = async () => {
  const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
  const posts = await res.json();
  return posts;
};

Esta função assíncrona faz uma solicitação à API REST do WordPress. Ela obtém todas as postagens disponíveis em seu site e as retorna como uma matriz.

Agora, vamos usar as postagens obtidas dentro de um componente de página simples do Next.js, exibindo-as no console e mostrando uma saudação básica:

const page = async () => {
  const posts = await getWpPosts();
  console.log(posts);
  
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default page;

Ao iniciar o projeto com o comando npm run dev, você verá a mensagem “Hello World” e os registros das postagens obtidas no terminal.

Os dados JSON representando as informações de cada postagem do Gutenberg incluem vários campos, entre os quais os campos de conteúdo (content) e de resumo (excerpt) são retornados como blocos HTML formatados do Gutenberg.

Para exibir corretamente este conteúdo HTML no Next.js, usamos a propriedade dangerouslySetInnerHTML:

const page = async () => {
  const posts = await getWpPosts();

  return (
    <>
      <h1>Headless Blog</h1>

      <div>
        {posts.map((post) => (
          <Link href={'/blog/' + post.id} key={post.id}>
            <h2>
              {post.title.rendered} <span>-></span>
            </h2>
            <div dangerouslySetInnerHTML={{ __html: post.excerpt.rendered }} />
          </Link>
        ))}
      </div>
    </>
  );
};

export default page;

Neste componente atualizado, iteramos sobre a matriz de postagens obtidas para criar uma lista de resumos. Cada resumo é envolto por um componente Link para navegação, exibindo o título da postagem e um trecho do seu conteúdo.

A propriedade dangerouslySetInnerHTML é usada para analisar e exibir o conteúdo HTML contido no campo excerpt.rendered.

A seguir, crie o arquivo blog/[id]/page.js dentro do diretório app. No Next.js, os diretórios são usados para definir rotas. Portanto, ao criar o diretório blog, você define a rota /blog/. Combinado com roteamento dinâmico, isso permite criar rotas para cada postagem individual.

Cada postagem possui um ID. Você usa este ID para criar sua rota única /blog/{post_id} em seu aplicativo. Adicione o seguinte código:

import Link from 'next/link';

export async function generateStaticParams() {
  const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
  const posts = await res.json();
  return posts.map((post) => {
    return {
      params: {
        id: post.id.toString(),
      },
    };
  });
}

export async function getPost(id) {
  const response = await fetch('https://yoursite.com/wp-json/wp/v2/posts/' + id);
  const post = await response.json();
  return post;
}

função generateStaticParams gera estática as rotas durante a compilação com base no ID correspondente retornado para cada postagem. A função getPost obtém os dados do Gutenberg da API REST para a postagem com o ID fornecido.

Na seção anterior, foram mostrados exemplos de dados do Gutenberg analisados retornados da API REST para a postagem. Neste ponto, estamos interessados apenas no campo content.rendered:

[ { ... "content": { "rendered" : "\n<p>Fire, a primal force, captivates with its <strong>flickering flames</strong>, evoking both awe and caution. Its <quote>dance</quote> symbolizes destruction and renewal, consuming the old to make way for the new. While it warms our homes and hearts, fire demands respect for its power to devastate.</p>\n\n\n\n<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="250" height="148" src="https://img.example.com/wp-content/uploads/2024/02/burningbuilding.jpg" alt="" class="wp-image-14"/></figure>\n\n\n\n<p>In ancient times, fire was a beacon of light and warmth, essential for survival. Today, it remains a symbol of human ingenuity and danger. From the comforting glow of a hearth to the destructive fury of wildfires, fire’s dual nature reminds us of our fragile relationship with the elements.</p>\n\n\n\n<figure class="wp-block-image size-large"><img decoding="async" src="https://img.example.com/premium-photo/painting-burning-building-illuminated-by-bright-flames-night_168058-249.jpg?w=1380" alt=""/></figure>\n\n\n\n<p>You can check out other articles on our blog:</p>\n\n\n\n<ul>\n<li><a href="https://yoursite.com/?p=6">Lorem Ipsum: Beginnings</a></li>\n\n\n\n<li><a href="https://yoursite.com/?p=9">Lorem Ipsum: Act 2</a></li>\n\n\n\n<li><a href="https://yoursite.com/?p=11">Lorem Ipsum: Act 3</a></li>\n</ul>\n" }, ... }]

Este campo contém o código HTML não processado da postagem. Você pode renderizá-lo diretamente usando a propriedade dangerouslySetInnerHTML da seguinte forma:

<div dangerouslySetInnerHTML={{ __html: <raw_html_string> }} />

Em seguida, você pode processar os dados, analisando os links internos e alterando o tamanho das imagens. Instale o pacote html-react-parser para simplificar o processo de análise das tags:

npm install html-react-parser --save

Adicione o seguinte código ao arquivo blog/[id]/page.js:

import parse, { domToReact } from "html-react-parser";

export function fixInternalLinks(html_string) {
  const pattern = /href="https:\/\/yoursite.com\/\?p=(\d+)"/g;
  const replacement = 'data-internal-link="true" href="/blog/$1"';

  return html_string.replace(pattern, replacement);
}

export function parseHtml(html) {
  const _content = html.replace(/\n{2,}/g, '<br />');
  const content = fixInternalLinks(_content);

  const options = {
    replace: ({ name, attribs, children }) => {
      const isInternalLink =
        name === "a" && attribs["data-internal-link"] === "true";

      if (isInternalLink) {
        return (
          <Link href={attribs.href} {...attribs}>
            {domToReact(children, options)}
          </Link>
        );
      } else if (name === "img") {
        attribs["width"] = "250";
        attribs["height"] = "150";
        return (
          <img {...attribs}/>
        );
      }
    },
  };

  return parse(content, options);
}

A função fixInternalLinks() usa uma expressão regular para encontrar links para postagens do seu site WordPress na string HTML. No código HTML original, você pode ver que a postagem contém uma tag <ul> com links para outras postagens em seu site. Esta função substitui esses links por links internos para as rotas do seu site estático.

A função parseHtml() encontra sequências adicionais de quebras de linha (\n) e as substitui por tags <br />. Também detecta links internos e converte as tags a em componentes Link. Em seguida, esta função altera o tamanho das imagens usando os atributos das tags.

Criando a interface principal

Para gerar a interface principal para cada rota dinâmica, adicione o seguinte código:

export default async function Post({ params }) {
  const post = await getPost(params.id);

  const content = parseHtml(post.content.rendered);

  return (
    <>
      <h1>
        {post.title.rendered}
      </h1>
 	 
      <div>{content}</div>
    </>
  );
}

Após analisar o código HTML não processado dos dados do Gutenberg, o código retorna JSX, representando a interface formatada da página.

Executando o projeto

Ao iniciar o projeto, na página inicial você verá uma lista de postagens do seu site WordPress. Além disso, ao navegar pelas postagens individuais, você verá o conteúdo dos blocos do Gutenberg renderizado corretamente.

Conclusão

Este guia explicou como integrar e analisar eficientemente o conteúdo dos blocos do Gutenberg em HTML usando a API do WordPress. Agora, você pode exibir qualquer tipo de conteúdo em seu frontend ao usar o WordPress sem interface gráfica.

Leave your thought here

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *