O Gutenberg é o editor predefinido do WordPress. Este editor permite que o conteúdo seja criado e projetado usando blocos discretos de texto, imagens, vídeo e outros elementos do site por meio de uma interface de arrastar e soltar. Esta abordagem aumenta a flexibilidade e as capacidades de design do WordPress.
Obter o Conteúdo do Gutenberg com a API REST
Para interagir programaticamente com um site WordPress e recuperar conteúdo estruturado em blocos Gutenberg, podes usar a API REST do WordPress ou o plugin WPGraphQL. Estas ferramentas permitem-te ir buscar conteúdo do WordPress em formato JSON.
Para permitir o acesso a dados JSON através da API REST, ajuste as definições de permalink do WordPress para longe de "Plain". Desta forma, a API pode ser acedida através de um URL num formato específico, como mostrado abaixo:
https://yoursite.com/wp-json/wp/v2
Ao enviar pedidos de API para este URL, pode recuperar programaticamente várias informações e executar acções no seu site WordPress. Por exemplo, pode obter uma lista de mensagens enviando um pedido GET para o seguinte endereço:
https://yoursite.com/wp-json/wp/v2/posts
É devolvido um objeto JSON com informações sobre a publicação no sítio WordPress, incluindo o título, o conteúdo, os detalhes do autor, etc.
Analisar blocos do Gutenberg em HTML
Ao recuperar posts de um site WordPress usando o editor Gutenberg, o conteúdo armazenado na base de dados pode usar uma mistura de metadados HTML e JSON para descrever vários tipos de blocos, como citações e galerias:
<!-- wp:quote {"className":"inspirational-quote","style":{"typography":{"fontSize":"large"}}} -->
<blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>"A viagem de mil milhas começa com um 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="http://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="Uma vista deslumbrante sobre as montanhas" class="wp-image-34"/></figure></li><li class="blocks-gallery-item"><figure><img src="http://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Serena margem do lago ao amanhecer" class="wp-image-35"/></figure></li></ul>
<!-- /wp:gallery -->
Este excerto mostra dois blocos do Gutenberg: uma citação e uma galeria. Cada bloco tem metadados JSON encapsulados em comentários HTML. Os metadados definem atributos como nomes de classes, estilos e outras configurações relacionadas com a apresentação dos blocos.
Quando vai buscar estes blocos através da API REST do WordPress ou do WPGraphQL, o WordPress processa-os e converte a combinação de metadados HTML e JSON em elementos HTML totalmente renderizados que pode integrar diretamente nas suas páginas. O HTML convertido do bloco acima é exibido abaixo:
<blockquote class="wp-block-quote inspirational-quote has-large-font-size"><p>"A viagem de mil milhas começa com um 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="http://example.com/wp-content/uploads/2021/09/image1-300x200.jpg" alt="Uma vista deslumbrante sobre as montanhas" class="wp-image-34" sizes="(max-width: 300px) 100vw, 300px" /></figure></li>
<li class="blocks-gallery-item"><figure><img loading="lazy" src="http://example.com/wp-content/uploads/2021/09/image2-300x200.jpg" alt="Serena margem do lago ao amanhecer" class="wp-image-35" sizes="(max-width: 300px) 100vw, 300px" /></figure></li>
</ul>
Para os programadores que criam aplicações desacopladas ou que utilizam estruturas JavaScript como o Next.js, isto proporciona uma forma fácil de apresentar conteúdo injectando HTML diretamente na página utilizando atributosperigosamenteSetInnerHTML
para apresentar os marcadores.
<div dangerouslysetinnerhtml="{{" __html: <raw_html_string> }} />
Analisar o conteúdo do bloco do Gutenberg no site estático Next.js
Extraímos o conteúdo do WordPress para um projeto Next.js e depois analisámos os blocos do Gutenberg em HTML.
1) Primeiro, configure uma função para obter mensagens do sítio WordPress. Abra a função src/page.js e substitua o 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();
const posts = await await res.json(); return posts;
};
Esta função assíncrona executa um pedido de API para a API REST do WordPress. Ela obtém todos os posts disponíveis em seu site e os retorna como uma matriz.
2) Em seguida, vamos utilizar a publicação obtida num componente de página Next.js simples, registando a publicação na consola e apresentando a saudação básica:
const page = async () => {
const posts = await getWpPosts(); console.log(posts);
console.log(posts);
return (
<div>
<h1>Olá mundo</h1>
</div>
);
}.
exportar página por defeito.
Quando se executa um projeto utilizandonpm run dev
Apresenta uma mensagem "Hello World" e regista a mensagem obtida no terminal.
[
{
"_links" : {
"about" : [...] ,
"autor" : [...] , "coleção" : [...] , "autor" : [...]
"coleção" : [...] , "curies" : [...] , "collection" : [...]
"curies" : [...] . ,
"predecessor-version" : [...] . , "replies" : [...] , "replies" : [...] , "predecessor-version" : [...]
"replies" : [...] . , "self" : [...] , "replies" : [...]
"self" : [...] , "version-history" : [...] , "replies" : [...] , "self" : [...]
"version-history" : [...] . , "wp:attachment" : [...] , "self" : [...] , "version-history" : [...]
"wp:attachment" : [...] . , "wp:term" : [...] , "version-history" : [...] , "wp:attachment" : [...]
"wp:termo" : [...] .
},
"categories" : [...] } , "comment_status" : "open", "comment_status" : "open", "wp:term" : [...] }
"comment_status" : "open", "content" : { "wp:term" : [...] }
"content" : {
"protected" : false, "rendered" : "\new", "content" : {
"renderizado" : "\n<p>O fogo, uma força primordial, cativa com a sua <strong>chamas tremeluzentes</strong>, evocando tanto o espanto como a prudência. <quote>dança</quote> simboliza a destruição e a renovação, consumindo o antigo para dar lugar ao novo. Ao mesmo tempo que aquece as nossas casas e os nossos corações, o fogo exige respeito pelo seu poder de devastar.</p>\n\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\n<p>Nos tempos antigos, o fogo era um farol de luz e calor, essencial para a sobrevivência. Atualmente, continua a ser um símbolo do engenho humano e do perigo. Do brilho reconfortante de uma lareira à fúria destrutiva dos incêndios florestais, a dupla natureza do fogo recorda-nos a nossa frágil relação com o mundo. Desde o brilho reconfortante de uma lareira até à fúria destrutiva dos incêndios florestais, a dupla natureza do fogo recorda-nos a nossa frágil relação com os elementos.</p>\n\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\n<p>Pode consultar outros artigos no nosso blogue.</p>\n\n\n\n\n<ul>\n<li><a href="https://www.361sale.com/pt/6/">Lorem Ipsum: Começos</a></li>\n\n\n\n\n<li><a href="https://www.361sale.com/pt/utilizador/">Lorem Ipsum: Ato 2</a></li>\n\n\n\n\n<li><a href="https://www.361sale.com/pt/account/">Lorem Ipsum: Ato 3</a></li>\n</ul>\n"
},
"date" : "2024-02-27T12:08:30",
"date_gmt" : "2024-02-27T12:08:30",
"excerto" : {
"protected" : falso, "rendered" :
"renderizado" : "<p>O fogo, uma força primordial, cativa com as suas chamas tremeluzentes, evocando tanto o espanto como a cautela. A sua dança simboliza a destruição e a renovação, consumindo o antigo para dar lugar ao novo. Ao mesmo tempo que aquece as nossas casas e os nossos corações, o fogo exige respeito pelo seu poder devastador. Nos tempos antigos, o fogo era um farol de luz e calor, [...]</p>\n"
},
"featured_media" : 0,
"formato" : "standard",
"guid" : {
"rendered" : "https://yoursite.com/?p=13"
},
"meta" : {
"notas de rodapé" : ""
},
"modelo" : "",
"título" : {
"renderizado" : "Fogo"
},
"tipo" : "post"
},
},
...
]
O objeto JSON que representa os dados para posts individuais do Gutenberg inclui vários campos, com os campos de conteúdo e de excerto devolvidos como blocos do Gutenberg analisados como cadeias HTML.
3) Para renderizar corretamente este conteúdo HTML em Next.js, utilizamos a funçãoperigosamenteSetInnerHTML
Atributos:
const page = async () => {
const posts = await getWpPosts();
return (
<>
<h1> Blogue sem cabeça </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>
</>
);
}.
exportar página por defeito.
No componente atualizado, mapeamos a matriz de mensagens obtidas para gerar uma lista de excertos de mensagens. Cada excerto está contido num ficheiroLigação
O título da publicação e o respetivo snippet de conteúdo são apresentados no componente utilizado para a navegação.
deveperigosamenteSetInnerHTML
Os atributos são utilizados para analisar e renderizarexcerto.renderizado
O conteúdo HTML contido no campo.
4.Em seguida, na aplicaçãoCriar um ficheiro no diretórioblogue/[id]/page.js . As rotas podem ser definidas através de pastas. Assim, um itinerário pode ser definido através da criação deblogue (palavra emprestada) pasta, é possível definirblogue (palavra emprestada) Rotas. Isto pode ser combinado com o encaminhamento dinâmico , que gera rotas para cada posto.
5) Cada mensagem tem um ID./blog/{post_id}
Gerar o seu caminho único na aplicação. Adicione o seguinte código:
importar Link de 'next/link';
exportar a função assíncrona generateStaticParams() {
const res = await fetch('https://yoursite.com/wp-json/wp/v2/posts');
const posts = await res.json(); return posts.map((post); }); })
return posts.map((post) => {
return {
params: {
id: post.id.toString(), { params: { post.id.
}, }
}; }
});
}
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; const post = await response.
const post = await response.json(); return post; }
}
devegenerateStaticParams()
gera caminhos estaticamente em tempo de construção com base nos IDs correspondentes retornados por cada post. A funçãogetPost()
A função obtém os dados do Gutenberg para o post a partir da API REST usando o ID passado.
A secção anterior mostra um exemplo de dados analisados do Gutenberg devolvidos pela API REST do post. Por agora, estamos apenas preocupados com ocontent.rendered
Campos:
[
{
...
"conteúdo": {
"renderizado" : "\n<p>O fogo, uma força primordial, cativa com a sua <strong>chamas tremeluzentes</strong>, evocando tanto o espanto como a prudência. <quote>dança</quote> simboliza a destruição e a renovação, consumindo o antigo para dar lugar ao novo. Ao mesmo tempo que aquece as nossas casas e os nossos corações, o fogo exige respeito pelo seu poder de devastar.</p>\n\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\n<p>Nos tempos antigos, o fogo era um farol de luz e calor, essencial para a sobrevivência. Atualmente, continua a ser um símbolo do engenho humano e do perigo. Do brilho reconfortante de uma lareira à fúria destrutiva dos incêndios florestais, a dupla natureza do fogo recorda-nos a nossa frágil relação com o mundo. Desde o brilho reconfortante de uma lareira até à fúria destrutiva dos incêndios florestais, a dupla natureza do fogo recorda-nos a nossa frágil relação com os elementos.</p>\n\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\n<p>Pode consultar outros artigos no nosso blogue.</p>\n\n\n\n\n<ul>\n<li><a> href=\"https://yoursite.com/?p=6\">Lorem Ipsum: Começos</a></li>\n\n\n\n\n<li><a> href=\"https://yoursite.com/?p=9\">Lorem Ipsum: Ato 2</a></li>\n\n\n\n\n<li><a> href=\"https://yoursite.com/?p=11\">Lorem Ipsum: Ato 3</a></li>\n</ul>\n"
},
...
}
]
Este campo contém o HTML em bruto da publicação, que pode ser utilizado diretamente com a funçãoperigosamenteSetInnerHTML
Imóveis como este rendem<div dangerouslysetinnerhtml="{{" __html: <raw_html_string> }} />
.
6) Em seguida, os dados podem ser processados analisando as ligações internas e redimensionando as imagens. Instalar oanalisador de reação html
para simplificar o processo de análise das etiquetas:
npm install html-react-parser --save
7) Adicione o seguinte código ablogue/[id]/page.js Documentação:
import parse, { domToReact } from "html-react-parser";
/*
* We use a regular expression (pattern) to match the specific URL you want to replace.
* The (\d+) part captures the numeric ID after ?p=.
* Then, we use the replacement string 'data-internal-link="true" href="/blog/$1"',
* where $1 is a placeholder for the captured ID.
*/
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) {
// Replace 2+ sequences of '\n' with a single '<br />' tag
const _content = html.replace(/\n{2,}/g, '<br />');
const content = fixInternalLinks(_content);
const options = {
replace: ({ name, attribs, children }) => {
// Convert internal links to Next.js Link components.
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);
}
devefixInternalLinks()
usa uma expressão regular para encontrar um link para um post no site do WordPress a partir de uma string de HTML. No HTML bruto, você pode ver que o post contém umLista
que contém ligações para outras publicações no sítio, e substitui essas ligações por ligações internas que apontam para caminhos no sítio estático.
deveparseHTML()
encontra várias sequências de novas linhas redundantes.n
e substituí-los por etiquetas<br />
. Também procura ligações internas e converte as etiquetas âncora em etiquetas de ligação. A função redimensiona a imagem utilizando o atributo tag.
8) Para gerar a IU principal para cada caminho dinâmico, 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>{conteúdo}</div>
</>
);
}
Depois de analisar o HTML em bruto a partir dos dados do Gutenberg, o código devolve JSX que representa a IU formatada da página.
Finalmente, quando executar o projeto, a página inicial mostrará uma lista de posts no WordPress. Além disso, quando clicar em posts individuais, verá o conteúdo analisado do Gutenberg renderizado corretamente.