Saltar al contenido

Genera páginas de etiquetas

Prepárate para…

  • Crea una página para generar múltiples páginas
  • Especifica qué rutas de página construir, y pasa a cada página sus propios props

Puedes crear conjuntos completos de páginas dinámicamente usando archivos .astro que exportan una función getStaticPaths().

  1. Crea un nuevo archivo en src/pages/tags/[tag].astro. (Tendrás que crear una nueva carpeta.) Nota que el nombre del archivo ([tag].astro) usa 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: "successes" } },
    { params: { tag: "community" } },
    { params: { tag: "blogging" } },
    { params: { tag: "setbacks" } },
    { params: { tag: "learning in public" } },
    ];
    }
    const { tag } = Astro.params;
    ---
    <BaseLayout pageTitle={tag}>
    <p>Posts tagged with {tag}</p>
    </BaseLayout>

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

  2. Si has personalizado tus posts de blog, entonces reemplaza los valores individuales de etiqueta (ej. "astro", "successes", "community", etc.) con las etiquetas usadas en tus propios posts.

  3. Asegúrate de que cada post de blog contenga al menos una etiqueta, escrita como un array, ej. tags: ["blogging"].

  4. Visita http://localhost:4321/tags/astro en la vista previa de tu navegador y deberías ver una página, generada dinámicamente desde [tag].astro. Verifica que también tienes páginas creadas para cada una de tus etiquetas en /tags/successes, /tags/community, y /tags/learning%20in%20public, etc., o en cada una de tus etiquetas personalizadas. Puede que necesites primero detener y reiniciar el dev server para ver estas nuevas páginas.

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

    Asegúrate de dar a cada ruta en tu array los nuevos props, y luego hacer esos props disponibles para tu plantilla de componente fuera de tu función.

    src/pages/tags/[tag].astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    export async function getStaticPaths() {
    const allPosts = Object.values(import.meta.glob('../posts/*.md', { eager: true }));
    return [
    {params: {tag: "astro"}, props: {posts: allPosts}},
    {params: {tag: "successes"}, props: {posts: allPosts}},
    {params: {tag: "community"}, props: {posts: allPosts}},
    {params: {tag: "blogging"}, props: {posts: allPosts}},
    {params: {tag: "setbacks"}, props: {posts: allPosts}},
    {params: {tag: "learning in public"}, props: {posts: allPosts}}
    ];
    }
    const { tag } = Astro.params;
    const { posts } = Astro.props;
    ---
  2. Filtra tu lista de posts, usando el soporte integrado de TypeScript de Astro, para incluir solo posts 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: any) => post.frontmatter.tags?.includes(tag));
    ---
  3. Ahora puedes actualizar tu plantilla HTML para mostrar una lista de cada post de 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>Posts tagged with {tag}</p>
    <ul>
    {filteredPosts.map((post: any) => <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>Posts tagged with {tag}</p>
    <ul>
    {filteredPosts.map((post: any) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
    {filteredPosts.map((post: any) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}
    </ul>
    </BaseLayout>
  5. Revisa la vista previa de tu navegador para tus páginas de etiquetas individuales, y ahora deberías ver una lista de todos tus posts de blog que contienen esa etiqueta en particular.

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

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

  2. La lista de rutas a generar (retornadas) por getStaticPaths()

  3. Los valores recibidos de props y params para ser usados en la plantilla HTML.

JavaScript avanzado: Genera páginas desde etiquetas existentes

Sección titulada “JavaScript avanzado: Genera páginas desde etiquetas existentes”

Tus páginas de etiquetas ahora están definidas estáticamente en [tag].astro. Si añades una nueva etiqueta a un post de blog, también tendrás que revisitar esta página y actualizar tus rutas de página.

El siguiente ejemplo muestra cómo reemplazar tu código en esta página con código que automáticamente buscará, y generará páginas para, cada etiqueta usada en tus páginas de blog.

  1. Verifica que todos tus posts de blog contengan etiquetas

    Revisa cada una de tus páginas Markdown existentes y asegúrate de que cada post contenga un array tags en su frontmatter. Incluso si solo tienes una etiqueta, debería seguir escribiéndose como un array, ej. tags: ["blogging"].

  2. Crea un array de todas tus etiquetas existentes usando el soporte integrado de TypeScript de Astro.

    Añade el siguiente código para proporcionarte una lista de cada etiqueta usada en tus posts de blog.

    src/pages/tags/[tag].astro
    ---
    import BaseLayout from '../../layouts/BaseLayout.astro';
    export async function getStaticPaths() {
    const allPosts = Object.values(import.meta.glob('../posts/*.md', { eager: true }));
    const uniqueTags = [...new Set(allPosts.map((post: any) => post.frontmatter.tags).flat())];
    }
    ¡Dime qué hace esta línea de código en más detalle!

    ¡Está bien si esto no es algo que habrías escrito tú mismo aún!

    Recorre cada post de Markdown, uno por uno, y combina cada array de etiquetas en un solo array más grande. Luego, hace un nuevo Set de todas las etiquetas individuales que encontró (para ignorar valores repetidos). Finalmente, convierte ese set en un array (sin duplicados), que puedes usar para mostrar una lista de etiquetas en tu página.

    Ahora tienes un array uniqueTags con elementos "astro", "successes", "community", "blogging", "setbacks", "learning in public"

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

    src/pages/tags/[tag].astro
    return [
    {params: {tag: "astro"}, props: {posts: allPosts}},
    {params: {tag: "successes"}, props: {posts: allPosts}},
    {params: {tag: "community"}, props: {posts: allPosts}},
    {params: {tag: "blogging"}, props: {posts: allPosts}},
    {params: {tag: "setbacks"}, props: {posts: allPosts}},
    {params: {tag: "learning in public"}, props: {posts: allPosts}}
    ]
    return uniqueTags.map((tag) => {
    const filteredPosts = allPosts.filter((post: any) => post.frontmatter.tags.includes(tag));
    return {
    params: { tag },
    props: { posts: filteredPosts },
    };
    });
  4. Una función getStaticPaths siempre debería retornar una lista de objetos conteniendo params (cómo llamar a cada ruta de página) y opcionalmente cualquier props (datos que quieres pasar a esas páginas). Antes, definiste cada nombre de etiqueta que sabías que era usado en tu blog y pasaste la lista completa de posts como props a cada página.

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

    Y, ahora la lista de todos los posts de blog es filtrada antes de que sea enviada a cada página como props. Asegúrate de eliminar la línea anterior de código que filtraba los posts, 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: any) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}
    {posts.map((post: any) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}
    </ul>

Para comprobar tu trabajo, o si solo quieres código completo y correcto para copiar en [tag].astro, aquí está cómo debería verse 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 = Object.values(import.meta.glob('../posts/*.md', { eager: true }));
const uniqueTags = [...new Set(allPosts.map((post: any) => post.frontmatter.tags).flat())];
return uniqueTags.map((tag) => {
const filteredPosts = allPosts.filter((post: any) => post.frontmatter.tags.includes(tag));
return {
params: { tag },
props: { posts: filteredPosts },
};
});
}
const { tag } = Astro.params;
const { posts } = Astro.props;
---
<BaseLayout pageTitle={tag}>
<p>Posts tagged with {tag}</p>
<ul>
{posts.map((post: any) => <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/community y deberías ver una lista solo de tus posts de blog con la etiqueta community. Similarmente http://localhost:4321/tags/learning%20in%20public debería mostrar una lista de los posts de blog etiquetados con learning in public.

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

Elige el término que coincida con la descripción.

  1. Una función que retorna un array de rutas de página.

  2. El proceso de crear múltiples rutas de página desde un archivo en Astro.

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

Contribuir Comunidad Patrocinar