Saltearse al contenido

Crear una página índice de etiquetas

Ahora que tienes páginas individuales para cada etiqueta, ¡es hora de crear enlaces a ellas!

Prepárate para...

  • Agregar una nueva página utilizando el patrón de enrutamiento /pages/folder/index.astro
  • Mostrar una lista de todas sus etiquetas únicas, con enlaces a cada página de etiquetas
  • Actualizar tu sitio con enlaces de navegación a esta nueva página de etiquetas

Utiliza el patrón de enrutamiento /pages/folder/index.astro

Sección titulada Utiliza el patrón de enrutamiento /pages/folder/index.astro

Para añadir una página de índice de etiquetas a tu sitio web, puedes crear un nuevo archivo en src/pages/tags.astro.

Pero, como ya tienes el directorio /tags/, puedes aprovechar otro patrón de enrutamiento en Astro, y mantener juntos todos tus archivos relacionados con etiquetas.

Pruébalo tú mismo: crea una página de índice de etiquetas

Sección titulada Pruébalo tú mismo: crea una página de índice de etiquetas
  1. Crea un nuevo fichero index.astro en el directorio src/pages/tags/.

  2. Ve a http://localhost:4321/tags y comprueba que tu sitio contiene ahora una página en esta URL. Estará vacía, pero existirá.

  3. Crea una página mínima en src/pages/tags/index.astro que utilice tu plantilla. Esto ya lo has hecho antes.

    Ampliar para ver los pasos
    1. Crea un nuevo componente de página en src/pages/tags/.

      Mostrar el nombre del archivo
      index.astro
    2. Importa y utiliza tu <BaseLayout>.

      Mostrar el código
      src/pages/tags/index.astro
      ---
      import BaseLayout from '../../layouts/BaseLayout.astro';
      ---
      <BaseLayout></BaseLayout>
    3. Define un título de página y pásalo a tu plantilla como atributo de componente.

      Mostrar el código
      src/pages/tags/index.astro
      ---
      import BaseLayout from '../../layouts/BaseLayout.astro';
      const pageTitle = "Índice de etiquetas";
      ---
      <BaseLayout pageTitle={pageTitle}></BaseLayout>
  4. Comprueba de nuevo la vista previa de tu navegador y deberías tener una página formateada, ¡lista para añadirle contenido!

Anteriormente has mostrado elementos en una lista desde un array usando map(). ¿Cómo sería definir un array con todas tus etiquetas y mostrarlas en una lista en esta página?

Ver el código
src/pages/tags/index.astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';
const tags = ['astro', 'bloguear', 'aprender en público', 'éxitos', 'contratiempos', 'comunidad']
const pageTitle = "Índice de etiquetas";
---
<BaseLayout pageTitle={pageTitle}>
<ul>
{tags.map((tag) => <li>{tag}</li>)}
</ul>
</BaseLayout>

Podrías hacer esto, pero entonces tendrías que volver a este archivo y actualizar tu array cada vez que utilices una nueva etiqueta en una futura entrada del blog.

Afortunadamente, ya conoces una forma de obtener los datos de todos tus archivos Markdown en una sola línea de código y luego devolver una lista de todas tus etiquetas.

  1. En src/pages/tags/index.astro, añade la línea de código al script frontmatter que dará acceso a tu página a los datos de cada archivo de entrada de blog .md.

    Ver el código
    src/pages/tags/index.astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    const allPosts = await Astro.glob('../posts/*.md');
    const pageTitle = "Índice de etiquetas";
    ---
  2. A continuación, añade la siguiente línea de JavaScript a tu componente de página. Es la misma que utilizaste en src/pages/tags/[tag].astro para devolver una lista de etiquetas ú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 etiquetas";
    ---

En lugar de crear elementos en una lista desordenada esta vez, crea un <p> para cada elemento, dentro de un <div>. El patrón debería resultarte familiar.

  1. Añade el siguiente código a tu plantilla de componentes:

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

    En la vista previa de tu navegador, comprueba que puedes ver tus etiquetas en la lista.

  2. Para que cada etiqueta enlace con su propia página, añade el siguiente enlace <a> al nombre de cada etiqueta:

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

Añade estilos a tu lista de etiquetas

Sección titulada Añade estilos a tu lista de etiquetas
  1. Añade las siguientes clases CSS para dar estilo a tu <div> y a cada <p> que se genere. Nota: Astro utiliza sintaxis HTML para añadir nombres de clases.

    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. Define estas nuevas clases CSS añadiendo la siguiente etiqueta <style> a esta 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. Comprueba la vista previa de tu navegador en http://localhost:4321/tags para verificar que tienes algunos estilos nuevos y que cada una de las etiquetas de la página tiene un enlace que funciona a su propia página de etiquetas individual.

Este es el aspecto que debería tener tu nueva página:

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 etiquetas";
---
<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>

Añade esta página a tu navegación

Sección titulada Añade esta página a tu navegación

En este momento, puedes navegar a http://localhost:4321/tags y ver esta página. Desde esta página, puedes hacer clic en los enlaces a sus páginas de etiquetas individuales.

Pero aún así, debes hacer que estas páginas se puedan descubrir desde otras páginas de tu sitio web.

  1. En tu componente Navigation.astro, incluye un enlace a esta nueva página de índice de etiquetas.

    Muéstrame el código
    src/components/Navigation.astro
    <a href="/">Inicio</a>
    <a href="/about/">Sobre mí</a>
    <a href="/blog/">Blog</a>
    <a href="/tags/">Etiquetas</a>

Reto: Incluye etiquetas en la plantilla de las entradas del blog

Sección titulada Reto: Incluye etiquetas en la plantilla de las entradas del blog

Ya has escrito todo el código que necesitas para mostrar también una lista de etiquetas en cada entrada del blog, y enlazarlas a sus páginas de etiquetas. Ya tienes trabajo que puedes reutilizar.

Sigue los pasos que se indican a continuación y comprueba tu trabajo comparándolo con la muestra de código final.

  1. Copia el <div class="tags">...</div> y <style>...</style> de src/pages/tags/index.astro y reutilízalo 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 de que este código funcione, necesitas hacer una pequeña edición al código que pegaste en MarkdownPostLayout.astro. ¿Puedes averiguar cuál es?

Dame una pista

¿Cómo se escriben los demás props (por ejemplo, título, autor, etc.) en la plantilla de diseño? ¿Cómo recibe la maquetación los accesorios de una entrada individual del blog?

¡Dame otra pista!

Para utilizar props (valores pasados) de una entrada de blog .md en tu plantilla, como etiquetas, necesitas agregar un prefijo especial al valor.

¡Enséñame el código!
src/layouts/MarkdownPostLayout.astro
<div class="tags">
{frontmatter.tags.map((tag) => (
<p class="tag"><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>

Registro de códigos: MarkdownPostLayout

Sección titulada Registro de códigos: MarkdownPostLayout

Para comprobar tu trabajo, o si simplemente quieres un código completo y correcto para copiar en MarkdownPostLayout.astro, aquí tienes el aspecto que debería tener tu componente de 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">
{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>

Coincide cada ruta de archivo con una segunda ruta de archivo que creará una página en la misma ruta.

  1. src/pages/categories.astro

  2. src/pages/posts.astro

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