No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripción 🔥

Aprende todo un fin de semana sin pagar una suscripción 🔥

Regístrate

Comienza en:

5D
13H
21M
24S

Markdown

13/25
Recursos

Aportes 3

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

En mi caso yo decidí aprovechar otra de las caracteristicas de Astro para hacer esto mismo, y es el uso de colecciones. Esto nos permite generar un esquema con todos los atributos necesarios que deben tener los contenidos que entren dentro de la colección. Para crear nuestras colecciones debemos definir un archivo config.ts con las colecciones que usaremos:

Ejemplo

import { z, defineCollection } from 'astro:content';

const postCollection = defineCollection({
  schema: z.object({
    title: z.string(),
    pubDate: z.string().datetime(),
    description: z.string(),
    image: z.string().optional(),
    tags: z.array(z.string()),
  }),
});

export const collections = {
  'posts': postCollection,
};

Astro viene con zod, una librería que nos permite generar una validación de esquemas con TypeScript, de está forma definimos las propiedades que debe cumplir nuestra colección, que crearemos con la función defineCollection. Por último exportamos un objeto collections con nuestras colecciones. Es importante saber que debe existir una carpeta con el mismo nombre por colección creada, y en dicha carpeta se encontrarán los ficheros pertenecientes a la colección.

Para consumir dicha colección en el index.astro hacemos lo siguiente:

---
import { getCollection } from "astro:content";
import Layout from "../layouts/Layout.astro"
import Card from "../components/Card.astro"
import Header from "../components/Header.astro";
import Hero from "../components/Hero.astro";

const postEntries = await getCollection('posts');
---

<Layout title="Astro Testing">
	<main>
		<Header title="Astro Testing"/>
		<Hero />
		<ul role="list" class="link-card-grid">
			{postEntries.map(post => (
				<Card title={post.data.title} time={post.data.pubDate} tags={post.data.tags}/>
			))}
		</ul>
	</main>
</Layout>

<style>
	main {
		margin: auto;
		padding: 1.5rem;
		max-width: 60ch;
	}
	.link-card-grid {
		display: grid;
		grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
		gap: 1rem;
		padding: 0;
	}
</style>

En este caso usamos la función getCollections para obtener todos los ficheros, y accedemos a los atributos del mismo a través de la propiedad data.

Otra forma de hacer esto es usando colecciones.
 
Una colección es cualquier directorio dentro de src/content
https://docs.astro.build/en/guides/content-collections
 

Creamos un subdirectorio dentro de content, en este subdirectorio incluimos nuestros archivos .md
https://docs.astro.build/en/guides/content-collections/#organizing-with-multiple-collections

📂content
		📂tips <- (este el el nuevo subdirectorio)
				-📄hello-astro.md
				-📄hello-js.md
				-📄hello-world.md

Luego modificamos nuestro archivo index.astro añadiendo getCollection (Esta función provista por Astro nos permite ejecutar una query la cual nos trae los elementos dentro de nuestro directorio content)
https://docs.astro.build/en/guides/content-collections/#querying-collections

// src/pages/index.astro
// ... other components
import { getCollection } from 'astro:content';
const allPosts = await getCollection('tips'); // Obtenemos la coleccion por el nombre de su directorio (tips)

//... layout
{
  allPosts.map(item=>(
    <Card
      title={item?.data?.title}
      time={item?.data?.pubDate}
      tags={item?.data?.tags}
    />
  ))
}

Usamos data envez de frontmatter.
 
Así quedaría nuestro archivo:

// src/pages/index.astro
---
import Layout from '../layouts/Layout.astro';
import Card from '../components/Card.astro';
import Header from '../components/Header.astro'
import Hero from '../components/Hero.astro';

import { getCollection } from 'astro:content';

const allPosts = await getCollection('tips');

---
<Layout title="Welcome to Astro.">
	<main>
		<Header title="Astro Tutorial"/>
		<Hero/>
		<ul role="list" class="link-card-grid">
      {
        allPosts.map(item=>(
          <Card
            title={item?.data?.title}
            time={item?.data?.pubDate}
            tags={item?.data?.tags}
          />
        ))
      }
		</ul>
	</main>
</Layout>
// ... styles

Hay algo que no se explicó en la clase, y es ¿Cómo renderizar el contenido del markdown en el componente Card?

En la clase, el profesor muestra que le pasa al componente Card por props el title, time y tags, los cuales obtiene de los archivos markdown en la propiedad frontmatter al realizar el map del array obtenido de Astro.glob().

Pero, el contenido como tal del markdown, ¿cómo los muestro en el componente?

  1. Debemos crear un <slot /> en el componente Card, donde ubicaremos el contenido a renderizar

Card.astro

//... contenido del componente

		<p class="mt-2 text-sm leading-relaxed text-gray-500 line-clamp-3">
			<slot /> <!-- su contenido es inyectado aquí -->
		</p>
		<div class="mt-4 flex flex-wrap gap-1">
			{
				tags.map((tag) => (
					<span class="whitespace-nowrap rounded-full bg-purple-100 px-2.5 py-0.5 text-xs text-purple-600">
						{tag}
					</span>
				))
			}
		</div>
  1. Astro nos proporciona en cada objeto del array devuelto por Astro.glob() un componente llamado Content que devuelve el contenido completo y renderizado del archivo.
    Debemos abrir y cerrar el componente Card, <Card></Card> para que podamos inyectar contenido en el slot, y adentro poder llamar el componente de esta forma:

Suponiendo que post es la variable que renderiza el objeto en el map, se llama a: <post.Content />

<Layout title="Welcome to Astro.">
	<main class="">
		<Header title="Astro Ameth" />
		<Hero />
		<ul role="list" class="link-card-grid">
      {
        allPost.map(post => {
          return <Card title={post.frontmatter.title} time={post.frontmatter.pubDate} tags={post.frontmatter.tags}><post.Content /></Card>
        })
      }
			
		</ul>
	</main>
</Layout>

Este componente renderizará el archivo en formato markdown que interprete el navegador.