Skip to content

Latest commit

 

History

History
330 lines (243 loc) · 13.5 KB

File metadata and controls

330 lines (243 loc) · 13.5 KB
type title i18nReady description
tutorial
Generar páginas de etiquetas
true
Tutorial: Crea tu primer blog con Astro — Utiliza getStaticPaths() para crear varias páginas (rutas) a la vez

import Box from '/components/tutorial/Box.astro'; import Checklist from '/components/Checklist.astro'; import MultipleChoice from '/components/tutorial/MultipleChoice.astro'; import Option from '/components/tutorial/Option.astro'; import PreCheck from '~/components/tutorial/PreCheck.astro'; import { Steps } from '@astrojs/starlight/components';

- 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:
```astro title="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.
  1. 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.

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

  3. 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.

```astro title="src/pages/tags/[tag].astro" ins={5,18} "props: {posts: allPosts}" 
---
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;
---
```
  1. Filtra tu lista de entradas para incluir solo las entradas que contengan la etiqueta propia de la página.

    ---
    const { tag } = Astro.params;
    const { posts } = Astro.props;
    const filteredPosts = posts.filter((post) => post.frontmatter.tags?.includes(tag));
    ---
  2. 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:

    <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>
  3. Incluso puedes refactorizar esto para usar tu componente <BlogPost /> en su lugar. (No olvides importar este componente en la parte superior de [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>
  4. 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.

    dentro `getStaticPaths` fuera `getStaticPaths`
  2. La lista de rutas que se van a generar (devolver) mediantegetStaticPaths().

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

    dentro `getStaticPaths` fuera `getStaticPaths`

:::note[Conclusión] Si necesitas información para construir las rutas de la 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 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.

:::note Aunque parezca un reto, puedes intentar seguir los pasos para construir esta función por ti mismo. Si no quieres repasar el código JavaScript requerido en este momento, puedes saltar a la versión final del código y usarlo directamente en tu proyecto, reemplazando el contenido existente. :::

  1. Revisa que todas tus entradas de blog contengan etiquetas.

    Vuelve a revisar cada una de tus páginas Markdown existentes y asegúrate de que cada entrada contenga un array tags en su frontmatter. Incluso si sólo tienes una etiqueta, debería estar escrita como un array, por ejemplo, tags: ["blogging"].

  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.

    ---
    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

      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 },
        };
      });
  4. 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.

    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:

---
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.

    params enrutamiento dinámico `getStaticPaths()` props
  2. El proceso de creación de varias rutas de páginas a partir de un archivo en Astro.

    params enrutamiento dinámico `getStaticPaths()` props
  3. Valor que define el nombre de una ruta de página generada dinámicamente.

    params enrutamiento dinámico `getStaticPaths()` props

Checklist

- [ ] Puedo generar páginas dinámicamente. - [ ] Puedo pasar `props` a cada ruta de página.

Recursos