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
Enrutamiento dinámico de páginas
Sección titulada “Enrutamiento dinámico de páginas”Puedes crear conjuntos completos de páginas dinámicamente usando archivos .astro que exportan una función getStaticPaths().
Crea páginas dinámicamente
Sección titulada “Crea páginas dinámicamente”-
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
getStaticPathsretorna un array de rutas de página, y todas las páginas en esas rutas usarán la misma plantilla definida en el archivo. -
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.
-
Asegúrate de que cada post de blog contenga al menos una etiqueta, escrita como un array, ej.
tags: ["blogging"]. -
Visita
http://localhost:4321/tags/astroen 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.
Usa props en rutas dinámicas
Sección titulada “Usa props en rutas dinámicas”-
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;--- -
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));--- -
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> -
¡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> -
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.
Analiza el patrón
Sección titulada “Analiza el patrón”Para cada uno de los siguientes, indica si el código está escrito dentro de la función getStaticPaths(), o fuera de ella.
-
La llamada a
import.meta.glob()para recibir información sobre todos tus archivos.mdpara pasar a cada ruta de página. -
La lista de rutas a generar (retornadas) por
getStaticPaths() -
Los valores recibidos de
propsyparamspara ser usados en la plantilla HTML.
Si necesitas información para construir las rutas de página, escríbela dentro de getStaticPaths().
Para recibir información en la plantilla HTML de una ruta de página, escríbela fuera de getStaticPaths().
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.
Incluso si parece desafiante, ¡puedes intentar seguir los pasos para construir esta función tú mismo! Si no quieres repasar el JavaScript requerido ahora mismo, puedes saltar a la versión terminada del código y usarla directamente en tu proyecto, reemplazando el contenido existente.
-
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
tagsen su frontmatter. Incluso si solo tienes una etiqueta, debería seguir escribiéndose como un array, ej.tags: ["blogging"]. -
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
Setde 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
uniqueTagscon elementos"astro","successes","community","blogging","setbacks","learning in public" -
Reemplaza el valor de
returnde la funcióngetStaticPathssrc/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 },};}); -
Una función
getStaticPathssiempre debería retornar una lista de objetos conteniendoparams(cómo llamar a cada ruta de página) y opcionalmente cualquierprops(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
uniqueTagspara 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
postsen lugar defilteredPosts.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>
Ejemplo de código final
Sección titulada “Ejemplo de código final”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:
---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.
Pon a prueba tu conocimiento
Sección titulada “Pon a prueba tu conocimiento”Elige el término que coincida con la descripción.
-
Una función que retorna un array de rutas de página.
-
El proceso de crear múltiples rutas de página desde un archivo en Astro.
-
Un valor que define el nombre de una ruta de página generada dinámicamente.