Pular para o conteúdo

Construa uma página de Índice de Tags

Agora que você tem páginas individuais para cada tag, é hora de fazer links para elas.

Se prepare para...

  • Adicionar uma nova página utilizando o padrão de roteamento /pages/pasta/index.astro
  • Mostrar uma lista de todas as suas tags únicas, fazendo links para cada página de tag
  • Atualizar seu site com links de navegação para essa nova página Tags

Utilize o padrão de roteamento /pages/pasta/index.astro

Seção intitulada Utilize o padrão de roteamento /pages/pasta/index.astro

Para adicionar uma página Índice de Tags ao seu website, você poderia criar um novo arquivo em src/pages/tags.astro.

Porém, já que você já tem o diretório /tags/, você pode se aproveitar de outro padrão de roteamento no Astro, e manter todos os seus arquivos relacionados à tags juntos.

Tente você mesmo - Faça uma página de Índice de Tags

Seção intitulada Tente você mesmo - Faça uma página de Índice de Tags
  1. Crie um novo arquivo index.astro no diretório src/pages/tags/.

  2. Navegue para http://localhost:4321/tags e verifique que seu site agora contém uma página nessa URL. Ela estará vazia, mas vai existir.

  3. Crie uma página mínima em src/pages/tags/index.astro que utiliza seu layout. Você já fez isso anteriormente!

    Expanda para ver as etapas
    1. Crie um novo componente de página em src/pages/tags/.

      Mostre o nome do arquivo
      index.astro
    2. Importe e utilize seu <BaseLayout>.

      Mostre o código
      src/pages/tags/index.astro
      ---
      import BaseLayout from '../../layouts/BaseLayout.astro';
      ---
      <BaseLayout></BaseLayout>
    3. Defina um título da página, e passe-o para o seu layout como um atributo do componente.

      Mostre o código
      src/pages/tags/index.astro
      ---
      import BaseLayout from '../../layouts/BaseLayout.astro';
      const pageTitle = "Índice de Tags";
      ---
      <BaseLayout pageTitle={pageTitle}></BaseLayout>
  4. Verifique sua pré-visualização do navegador novamente e você deve ter uma página formatada, pronta para adicionar conteúdo nela!

Você havia anteriormente mostrado itens em uma lista de um array utilizando map(). Como se pareceria definir um array de todas as suas tags, e então mostrá-las em uma lista nessa página?

Veja o código
src/pages/tags/index.astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';
const tags = ['astro', 'blogar', 'aprender em público', 'sucessos', 'contratempos', 'comunidade'];
const pageTitle = "Índice de Tags";
---
<BaseLayout pageTitle={pageTitle}>
<ul>
{tags.map((tag) => <li>{tag}</li>)}
</ul>
</BaseLayout>

Você poderia fazer isso, mas então você teria que voltar para esse arquivo e atualizar seu array toda vez que você utiliza uma nova tag em uma futura postagem no blog.

Felizmente, você já sabe uma forma de conseguir os dados de todos os seus arquivos Markdown em uma linha de código, e então retornar uma lista de todas as suas tags.

  1. Em src/pages/tags/index.astro, adicione a linha de código para o script frontmatter que irá dar à sua página acesso aos dados de todo arquivo .md de postagem do blog.

    Veja o código
    src/pages/tags/index.astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = await Astro.glob('../posts/*.md');
    const pageTitle = "Índice de Tags";
    ---
  2. Depois, adicione a seguinte linha de JavaScript ao seu componente da página. Essa é a mesma linha que você utilizou em src/pages/tags/[tag].astro para retornar uma lista de tags únicas.

    src/pages/tags/index.astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = await Astro.glob('../posts/*.md');
    const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
    const pageTitle = "Índice de Tags";
    ---

Ao invés de criar items em uma lista desordenada dessa vez, crie um <p> para cada item, dentro de <div>. O padrão deve parecer familiar!

  1. Adicione o seguinte código para seu template do componente:

    src/pages/tags/index.astro
    <BaseLayout pageTitle={pageTitle}>
    <div>{tags.map((tag) => <p>{tag}</p>)}</div>
    </BaseLayout>

    Na sua pré-visualização do navegador, verifique que você pode ver suas tags listadas.

  2. Para fazer cada tag ter um link para sua própria página, adicione o seguinte link <a> para cada nome de tag:

    src/pages/tags/index.astro
    <BaseLayout pageTitle={pageTitle}>
    <div>
    {tags.map((tag) => (
    <p><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
    </div>
    </BaseLayout>
  1. Adicione as seguintes classes CSS para estilizar tanto sua <div> quanto cada <p> que será gerado. Nota: Astro utiliza a sintaxe do HTML para adicionar nomes de classes!

    src/pages/tags/index.astro
    <BaseLayout pageTitle={pageTitle}>
    <div class="tags">
    {tags.map((tag) => (
    <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
    </div>
    </BaseLayout>
  2. Defina essas novas classes CSS adicionando a seguinte tag <style> para essa página:

    src/pages/tags/index.astro
    <style>
    a {
    color: #00539F;
    }
    .tags {
    display: flex;
    flex-wrap: wrap;
    }
    .tag {
    margin: 0.25em;
    border: dotted 1px #a1a1a1;
    border-radius: .5em;
    padding: .5em 1em;
    font-size: 1.15em;
    background-color: #F8FCFD;
    }
    </style>
  3. Cheque a pré-visualização do seu navegador em http://localhost:4321/tags para verificar que você tem uns novos estilos e que cada uma das tags na página tem um link funcional para sua própria página de tag individual.

Aqui está como sua nova página deve se parecer:

src/pages/tags/index.astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';
const allPosts = await Astro.glob('../posts/*.md');
const tags = [...new Set(allPosts.map((post) => post.frontmatter.tags).flat())];
const pageTitle = "Índice de Tags";
---
<BaseLayout pageTitle={pageTitle}>
<div class="tags">
{tags.map((tag) => (
<p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>
</BaseLayout>
<style>
a {
color: #00539F;
}
.tags {
display: flex;
flex-wrap: wrap;
}
.tag {
margin: 0.25em;
border: dotted 1px #a1a1a1;
border-radius: .5em;
padding: .5em 1em;
font-size: 1.15em;
background-color: #F8FCFD;
}
</style>

Adicione essa página à sua navegação

Seção intitulada Adicione essa página à sua navegação

Neste momento, você pode navegar para http://localhost:4321/tags e ver essa página. A partir dessa página, você pode clicar em links para suas páginas individuais de tags.

Porém, você ainda precisa fazer com que essas páginas possam ser encontradas a partir de outras páginas no seu website.

  1. Em seu componente Navigation.astro, inclua um link para essa nova página Índice de Tags.

    Me mostre o código
    src/components/Navegacao.astro
    <a href="/">Início</a>
    <a href="/about/">Sobre</a>
    <a href="/blog/">Blog</a>
    <a href="/tags/">Tags</a>

Desafio: Inclua tags em seu layout de postagem do blog

Seção intitulada Desafio: Inclua tags em seu layout de postagem do blog

Agora você escreveu todo o código que você precisa para também mostrar uma lista de tags em cada postagem do blog, e fazer links para suas páginas de tag. Você tem trabalho existente que pode reutilizar!

Siga as etapas abaixo, e então cheque seu trabalho o comparando com a amostra de código final.

  1. Copie <div class="tags">...</div> e <style>...</style> de src/pages/tags/index.astro e o reutilize dentro de MarkdownPostLayout.astro:

    src/layouts/MarkdownPostLayout.astro
    ---
    import BaseLayout from './BaseLayout.astro';
    const { frontmatter } = Astro.props;
    ---
    <BaseLayout pageTitle={frontmatter.title}>
    <p><em>{frontmatter.description}</em></p>
    <p>{frontmatter.pubDate.toString().slice(0,10)}</p>
    <p>Escrito por: {frontmatter.author}</p>
    <img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
    <div class="tags">
    {tags.map((tag) => (
    <p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
    ))}
    </div>
    <slot />
    </BaseLayout>
    <style>
    a {
    color: #00539F;
    }
    .tags {
    display: flex;
    flex-wrap: wrap;
    }
    .tag {
    margin: 0.25em;
    border: dotted 1px #a1a1a1;
    border-radius: .5em;
    padding: .5em 1em;
    font-size: 1.15em;
    background-color: #F8FCFD;
    }
    </style>

Antes desse código funcionar, você precisa fazer uma pequena modificação no código que você colou em MarkdownPostLayout.astro. Você consegue descobrir qual é a modificação?

Me dê uma dica

Como estão as outras props (e.x. title, author, etc.) escritas no template do seu layout? Como seu layout recebe props de uma postagem individual do blog?

Me dê outra dica!

Para que se utilize props (valores passados) de uma postagem do blog .md em seu layout, como tags, você precisa prefixar o valor com uma certa palavra.

Me mostre o código!
src/layouts/MarkdownPostLayout.astro
<div class="tags">
{frontmatter.tags.map((tag) => (
<p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>

Check In de Código: MarkdownPostLayout

Seção intitulada Check In de Código: MarkdownPostLayout

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

src/layouts/MarkdownPostLayout.astro
---
import BaseLayout from './BaseLayout.astro';
const { frontmatter } = Astro.props;
---
<BaseLayout pageTitle={frontmatter.title}>
<p><em>{frontmatter.description}</em></p>
<p>{frontmatter.pubDate.toString().slice(0,10)}</p>
<p>Escrito por: {frontmatter.author}</p>
<img src={frontmatter.image.url} width="300" alt={frontmatter.image.alt} />
<div class="tags">
{frontmatter.tags.map((tag) => (
<p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>
<slot />
</BaseLayout>
<style>
a {
color: #00539F;
}
.tags {
display: flex;
flex-wrap: wrap;
}
.tag {
margin: 0.25em;
border: dotted 1px #a1a1a1;
border-radius: .5em;
padding: .5em 1em;
font-size: 1.15em;
background-color: #F8FCFD;
}
</style>

Corresponda cada caminho de arquivo com um segundo caminho de arquivo que irá criar uma página na mesma rota.

  1. src/pages/categorias.astro

  2. src/pages/posts.astro

  3. src/pages/products/sapatos/index.astro