Saltearse al contenido

Generar páginas de etiquetas

Prepárate para...

  • Crear una página para generar varias páginas
  • Especificar qué rutas de página construir, y pasa a cada página sus propios props

Enrutamiento dinámico de páginas

Puedes crear conjuntos completos de páginas de forma dinámica utilizando archivos .astro que exporten una función getStaticPaths().

Crea páginas dinámicamente

  1. Crea un nuevo archivo en src/pages/tags/[tag].astro. (Tendrás que crear una nueva carpeta) Observa que el nombre del archivo ([tag].astro) utiliza corchetes. Pega el siguiente código en el archivo:

    src/pages/tags/[tag].astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    export async function getStaticPaths() {
    return [
    { params: { tag: "astro" } },
    { params: { tag: "éxitos" } },
    { params: { tag: "comunidad" } },
    { params: { tag: "bloguear" } },
    { params: { tag: "contratiempos" } },
    { params: { tag: "aprender en público" } },
    ];
    }
    const { tag } = Astro.params;
    ---
    <BaseLayout pageTitle={tag}>
    <p>Entradas etiquetadas con {tag}</p>
    </BaseLayout>

    La función getStaticPaths devuelve un array de rutas de páginas, y todas las páginas en esas rutas usarán la misma plantilla definida en el fichero.

  2. Si has personalizado las entradas de tu blog, sustituye los valores de las etiquetas individuales (por ejemplo, “astro”, “éxitos”, “comunidad”, etc.) por las etiquetas utilizadas en tus propias entradas.

  3. Asegúrate de que cada entrada del blog contiene al menos una etiqueta, escrita como un array, por ejemplo tags: ["bloguear"].

  4. Visita http://localhost:4321/tags/astro en la vista previa de tu navegador y deberías ver una página, generada dinámicamente a partir de [tag].astro. Comprueba que también tienes páginas creadas para cada una de tus etiquetas en /tags/éxitos, /tags/comunidad, y /tags/aprender%20en%20publico, etc., o en cada una de tus etiquetas personalizadas. Es posible que primero tengas que salir y reiniciar el servidor de desarrollo para ver estas nuevas páginas.

Utiliza props en rutas dinámicas

  1. Añade los siguientes props a tu función getStaticPaths() para que los datos de todas las entradas de tu blog estén disponibles para cada ruta de página.

    Asegúrate de dar a cada ruta de tu array los nuevos props, y luego haz que esos props estén disponibles para tu plantilla de componentes fuera de tu función.

    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: "éxitos"}, props: {posts: allPosts}},
    {params: {tag: "comunidad"}, props: {posts: allPosts}},
    {params: {tag: "bloguear"}, props: {posts: allPosts}},
    {params: {tag: "contratiempos"}, props: {posts: allPosts}},
    {params: {tag: "aprender en público"}, props: {posts: allPosts}}
    ]
    }
    const { tag } = Astro.params;
    const { posts } = Astro.props;
    ---
  2. Filtra tu lista de entradas para incluir solo las entradas que contengan la etiqueta propia de la 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. Ahora puedes actualizar tu plantilla HTML para mostrar una lista de cada entrada del blog que contenga la etiqueta propia de la página. Añade el siguiente código a [tag].astro:

    src/pages/tags/[tag].astro
    <BaseLayout pageTitle={tag}>
    <p>Entradas etiquetadas con {tag}</p>
    <ul>
    {filteredPosts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
    </ul>
    </BaseLayout>
  4. Incluso puedes refactorizar esto para usar tu componente <BlogPost /> en su lugar. (No olvides importar este componente en la parte superior de [tag].astro).

    src/pages/tags/[tag].astro
    <BaseLayout pageTitle={tag}>
    <p>Entradas etiquetadas con {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. Verifica la vista previa de tu navegador para las páginas de etiquetas individuales, y ahora deberías ver una lista de todas tus entradas de blog que contienen esa etiqueta particular.

Analiza el patrón

Para cada uno de los siguientes, indica si el código está escrito dentro de la función getStaticPath(), o fuera de ella.

  1. La llamada Astro.glob() para recibir información sobre todos tus archivos .md para pasar a cada ruta de página.

  2. La lista de rutas que se van a generar (devolver) mediantegetStaticPaths().

  3. Los valores recibidos de props y params que se utilizarán en la plantilla HTML.

JavaScript avanzado: Genera páginas a partir de etiquetas existentes

Tus páginas de etiquetas ahora están definidas estáticamente en [tag].astro. Si agregas una nueva etiqueta a una publicación de blog, también deberás visitar esta página y actualizar las rutas de tus páginas.

El siguiente ejemplo muestra cómo sustituir el código de esta página por un código que buscará automáticamente y generará páginas para cada etiqueta utilizada en las páginas de tu blog.

1. Comprueba que todas las entradas de tu blog contienen etiquetas

Revisa cada una de tus páginas Markdown existentes y asegúrate de que cada entrada contiene un array tags en su frontmatter. Incluso si sólo tiene una etiqueta, debe escribirse como un array, por ejemplo, tags: ["bloguear"].

2. Crea un array con todas las etiquetas existentes

Añade el siguiente código para obtener una lista de todas las etiquetas utilizadas en las entradas de tu 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())];
¡Dime con más detalle qué hace esta línea de código!

¡Está bien si esto no es algo que hubieras escrito tú mismo todavía!

Recorre cada entrada Markdown, una a una, y combina cada array de etiquetas en un único array más grande. A continuación, crea un nuevo Set a partir de todas las etiquetas individuales que ha encontrado (para ignorar los valores repetidos). Finalmente, convierte ese conjunto en un array (sin duplicaciones), que puedes usar para mostrar una lista de etiquetas en tu página.

Ahora tienes un array uniqueTags con los elementos "astro", "éxitos", "comunidad", "bloguear", "contratiempos", "aprender en público".

3. Sustituye el valor return de la función getStaticPaths

src/pages/tags/[tag].astro
return [
{params: {tag: "astro"}, props: {posts: allPosts}},
{params: {tag: "éxitos"}, props: {posts: allPosts}},
{params: {tag: "comunidad"}, props: {posts: allPosts}},
{params: {tag: "bloguear"}, props: {posts: allPosts}},
{params: {tag: "contratiempos"}, props: {posts: allPosts}},
{params: {tag: "aprender en 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 },
};
});

Una función getStaticPaths siempre debe devolver una lista de objetos que contengan params (cómo llamar a cada ruta de página) y opcionalmente cualquier props (datos que quieras pasar a esas páginas). Anteriormente, definiste cada nombre de etiqueta que sabías que se usaba en tu blog y pasaste toda la lista de entradas como props a cada página.

Ahora, generas esta lista de objetos automáticamente utilizando tu array uniqueTags para definir cada parámetro.

Y, ahora la lista de todas las publicaciones del blog es filtrada antes de ser enviada a cada página como props. Asegúrate de eliminar la línea de código anterior que filtra las publicaciones, y actualiza tu plantilla HTML para usar posts en lugar 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>

Ejemplo de código final

Para comprobar tu trabajo, o si simplemente quieres un código completo y correcto para copiar en [tag].astro, aquí tienes el aspecto que debería tener tu componente de Astro:

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>Posts etiquetados con {tag}</p>
<ul>
{posts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}
</ul>
</BaseLayout>

Ahora, deberías poder visitar cualquiera de tus páginas de etiquetas en la vista previa de tu navegador.

Navega a http://localhost:4321/tags/comunidad y verás una lista sólo de las entradas de tu blog con la etiqueta comunidad. Del mismo modo, http://localhost:4321/tags/aprender%20en%20público debería mostrar una lista de las entradas del blog con la etiqueta aprender en público.

En la siguiente sección, crearás enlaces de navegación a estas páginas.

Pon a prueba tus conocimientos

Elije el término que corresponda a la descripción.

  1. Función que devuelve un array de rutas de páginas.

  2. El proceso de creación de varias rutas de páginas a partir de un archivo en Astro.

  3. Valor que define el nombre de una ruta de página generada dinámicamente.

Checklist

Recursos