Pular para o conteúdo

Gere páginas de tags

Se prepare para...

  • Criar uma página para gerar múltiplas páginas
  • Especificar quais rotas de página construir, e passar em cada página suas próprias props

Você pode criar conjuntos inteiros de páginas dinamicamente utilizando arquivos .astro que exportam uma função getStaticPaths().

  1. Crie um novo arquivo em src/pages/tags/[tag].astro. (Você vai ter que criar uma nova pasta.) Note que o nome de arquivo ([tag].astro) usa colchetes. Cole o seguinte código no arquivo:

    src/pages/tags/[tag].astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    export async function getStaticPaths() {
    return [
    { params: { tag: "astro" } },
    { params: { tag: "sucessos" } },
    { params: { tag: "comunidade" } },
    { params: { tag: "blogueirando" } },
    { params: { tag: "contratempos" } },
    { params: { tag: "aprendendo em público" } },
    ];
    }
    const { tag } = Astro.params;
    ---
    <BaseLayout pageTitle={tag}>
    <p>Postagens com a tag {tag}</p>
    </BaseLayout>

    A função getStaticPaths retorna uma array de rotas de páginas, e todas as páginas nessas rotas vão utilizar o mesmo template definido no arquivo.

  2. Se você customizou suas postagens do blog, então substitua os valores individuais de tag (e.x. “astro”, “sucessos”, “comunidade”, etc.) com as tags utilizadas em suas próprias postagens.

  3. Certifique-se de que toda postagem do blog contém pelo menos uma tag, escrito como um array, e.x. tags: ["blogueirando"].

  4. Visite http://localhost:4321/tags/astro na pré-visualização do seu navegador e você deve ver uma página, gerada dinamicamente de [tag].astro. Verifique que você também tem páginas criadas para cada uma das suas tags em /tags/sucessos, /tags/comunidade, /tags/aprendendo%20em%20público, etc., ou para cada uma de suas tags customizadas. Você pode precisar fechar e reiniciar o servidor de desenvolvimento primeiro para ver essas novas páginas.

  1. Adicione as seguintes props a sua função getStaticPaths() para fazer com que os dados de todas as suas postagens do blog sejam disponibilizados para cada rota de página.

    Certifique-se de dar novas props para cada rota em seu array, e então faça essas props disponíveis ao seu template do componente fora da sua função.

    src/pages/tags/[tag].astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    export async function getStaticPaths() {
    const allPosts = await Astro.glob('../posts/*.md');
    return [
    {params: {tag: "astro"}, props: {posts: allPosts}},
    {params: {tag: "sucessos"}, props: {posts: allPosts}},
    {params: {tag: "comunidade"}, props: {posts: allPosts}},
    {params: {tag: "blogueirando"}, props: {posts: allPosts}},
    {params: {tag: "contratempos"}, props: {posts: allPosts}},
    {params: {tag: "aprendendo em público"}, props: {posts: allPosts}}
    ]
    }
    const { tag } = Astro.params;
    const { posts } = Astro.props;
    ---
  2. Filtre sua lista de postagens para apenas incluir postagens que contém a tag da própria página.

    /src/pages/tags/[tag].astro
    ---
    const { tag } = Astro.params;
    const { posts } = Astro.props;
    const filteredPosts = posts.filter((post) => post.frontmatter.tags?.includes(tag));
    ---
  3. Agora você pode atualizar seu template HTML para mostrar uma lista de cada postagem do blog contendo a tag da própria página. Adicione o seguinte código em [tag].astro:

    src/pages/tags/[tag].astro
    <BaseLayout pageTitle={tag}>
    <p>Postagens com a tag {tag}</p>
    <ul>
    {filteredPosts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
    </ul>
    </BaseLayout>
  4. Você pode até refatorar para utilizar seu componente <BlogPost /> no lugar! (Não se esqueça de importar esse componente no topo de [tag].astro.)

    src/pages/tags/[tag].astro
    <BaseLayout pageTitle={tag}>
    <p>Postagens com a tag {tag}</p>
    <ul>
    {filteredPosts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
    {filteredPosts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}
    </ul>
    </BaseLayout>
  5. Verifique a pré-visualização do seu navegador para as páginas de tag individuais, e você deve agora ver uma lista de todas as suas postagens do blog contendo aquela tag em particular.

Para cada uma das seguintes, diga se o código é escrito dentro da função getStaticPaths(), ou fora dela.

  1. A chamada de Astro.glob() para receber informação sobre todos os seus arquivos .md para passar para cada rota de página.

  2. A lista de rotas a serem geradas (retornadas) por getStaticPaths()

  3. Os valores recebidos de props e params a serem utilizados no template HTML.

JavaScript Avançado: Gere páginas a partir de tags existentes

Seção intitulada JavaScript Avançado: Gere páginas a partir de tags existentes

Suas páginas de tags são atualmente definidas estaticamente em [tag].astro. Se você quiser adicionar uma nova tag a uma postagem do blog, você também vai precisar revisitar essa página e atualizar suas rotas da página.

O exemplo a seguir mostra como substituir seu código nessa página com código que irá automaticamente procurar por, e gerar páginas para, cada tag usada em suas postagens do blog.

1. Verifique que todas as suas postagens do blog contém tags

Seção intitulada 1. Verifique que todas as suas postagens do blog contém tags

Revisite cada uma das suas páginas Markdown existentes e garanta que toda postagem contém um array de tags em seu frontmatter. Mesmo que você tenha apenas uma tag, ele deve continuar sendo escrito como um array, e.x. tags: ["blogueirando"].

2. Crie um array de todas as suas tags existentes

Seção intitulada 2. Crie um array de todas as suas tags existentes

Adicione o seguinte código para fornecê-lo com uma lista de cada tag utilizada em suas postagens do blog.

src/pages/tags/[tag].astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';
export async function getStaticPaths() {
const allPosts = await Astro.glob('../posts/*.md');
const uniqueTags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
Me diga o que esta linha de código está fazendo com mais detalhes!

Está tudo bem se isso não é algo que você teria escrito por você mesmo ainda!

Ela vai por cada postagem Markdown, uma por uma, e combina cada array de tags em um único array maior. Então, ela faz um novo Set a partir de todas as tags individuais encontradas (para ignorar valores repetidos). Finalmente, ela torna aquele set em um array (sem duplicações), que você pode usar para mostrar uma lista de tags em sua página.

Agora você tem um array uniqueTags com os itens de elemento "astro", "sucessos", "comunidade", "blogueirando", "contratempos", "aprendendo em público"

3. Substitua o valor de return da função getStaticPaths

Seção intitulada 3. Substitua o valor de return da função getStaticPaths
src/pages/tags/[tag].astro
return [
{params: {tag: "astro"}, props: {posts: allPosts}},
{params: {tag: "sucessos"}, props: {posts: allPosts}},
{params: {tag: "comunidade"}, props: {posts: allPosts}},
{params: {tag: "blogueirando"}, props: {posts: allPosts}},
{params: {tag: "contratempos"}, props: {posts: allPosts}},
{params: {tag: "aprendendo em público"}, props: {posts: allPosts}}
]
return uniqueTags.map((tag) => {
const filteredPosts = allPosts.filter((post) => post.frontmatter.tags.includes(tag));
return {
params: { tag },
props: { posts: filteredPosts },
};
});

Uma função getStaticPaths deve sempre retornar uma lista de objetos contendo params (do que chamar cada rota de página) e opcionalmente quaisquer props (dados que você quer passar para essas páginas). Anteriormente, você definiu cada nome de tag que você sabia que estava sendo utilizada em sua seu blog e passou a lista inteira de postagens como props para cada página.

Agora, você gerou essa lista de objetos automaticamente utilizando seu array uniqueTags para definir cada parâmetro.

E agora, a lista de todas as postagens do blog é filtrada antes de ser enviada para cada página como props. Certifique-se de remover a linha de código usada anteriormente para filtrar as postagens, e atualize seu template HTML para utilizar posts ao invés de filteredPosts.

src/pages/tags/[tag].astro
const { tag } = Astro.params;
const { posts } = Astro.props;
const filteredPosts = posts.filter((post) => post.frontmatter.tags?.includes(tag));
---
<!-- -->
<ul>
{filteredPosts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}
{posts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}
</ul>

Para verificar seu trabalho, ou se você só quer um código completo e correto para copiar em [tag].astro, aqui está como o seu componente Astro deve ficar:

src/pages/tags/[tag].astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';
import BlogPost from '../../components/BlogPost.astro';
export async function getStaticPaths() {
const allPosts = await Astro.glob('../posts/*.md');
const uniqueTags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
return uniqueTags.map((tag) => {
const filteredPosts = allPosts.filter((post) => post.frontmatter.tags.includes(tag));
return {
params: { tag },
props: { posts: filteredPosts },
};
});
}
const { tag } = Astro.params;
const { posts } = Astro.props;
---
<BaseLayout pageTitle={tag}>
<p>Postagens com a tag {tag}</p>
<ul>
{posts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}
</ul>
</BaseLayout>

Agora, você deve ser capaz de visitar qualquer uma das suas páginas de tag na sua pré-visualização do navegador.

Navegue para http://localhost:4321/tags/comunidade e você deve ver uma lista com apenas suas postagens do blog com a tag comunidade. Da mesma forma que http://localhost:4321/tags/aprendendo%20em%20publico deve apenas mostrar uma lista de postagens do blog com a tag aprendendo em público.

Na próxima seção, você irá criar links de navegação para essas páginas.

Escolha o termo que corresponde com a descrição.

  1. Uma função que retorna um array de rotas de página.

  2. O processo de criar múltiplas rotas de página a partir de um arquivo no Astro.

  3. Um valor que define o nome de uma rota de página gerada dinamicamente.