No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Markdown

13/25
Recursos

Aportes 6

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

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.

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.

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

Markdown

Markdown se usa com煤nmente usado para crear contenido, como publicaciones de blog y documentaci贸n. Dicha lenguaje, en Astro se incluye el soporte para documentos en Markdown.
.
Al igual que otros contenidos, podemos generar rutas como vistas dentro del subdirectorio ./src/pages.
.
src/pages/page-1.md

---
title: Hello, World
---

# Hi there!

This Markdown file creates a page at `your-domain.com/page-1/`

It probably isn't styled much, but Markdown does support:
- **bold** and _italics._
- lists
- [links](https://astro.build)
- and more!

Como caracter铆stica especial, con Markdown podemos generar contenido a partir de colecciones.
.

鉁 Concepto clave
Las colecciones nos ayudan a organizar nuestro contenido en volumen, similar entre s铆 para generar cat谩logos o grupos taxon贸micos de informaci贸n (productos, autores, etc.).

.

Caracter铆sticas de Markdown

Astro, provee de utilidades como caracter铆sticas con los que potencian el uso de Markdown, inyectando y vinculando propiedades 煤tiles como metadata, enrutamiento, etc.
.
Para el caso de metadata, podemos definir atributos de nuestro contenido para despu茅s ser presentado y organizado por alg煤n layout mediante frontmatter
.
src/pages/posts/post-1.md

---
layout: ../../layouts/BlogPostLayout.astro
title: Astro in brief
author: Himanshu
description: Find out what makes Astro awesome!
--- 
This is a post written in Markdown.

.
src/layouts/BlogPostLayout.astro

---
const {frontmatter} = Astro.props;
---
<html>
  <!-- ... -->
  <h1>{frontmatter.title}</h1>
  <h2>Post author: {frontmatter.author}</h2>
  <p>{frontmatter.description}</p>
  <slot /> <!-- Markdown content is injected here -->
   <!-- ... -->
</html>

Importando contenido en Markdown

Pese a que podemos emplear una p谩gina escrita en Markdown para que, despu茅s sea dispuesta en el router. Podemos emplear el contenido de Markdown como un repositorio de contenido y disponerla en una p谩gina, escrita en .astro por ejemplo, para organizarla seg煤n alguna presentaci贸n.
.
/src/pages/posts/great-post.md

---
title: 'The greatest post of all time'
author: 'Ben'
---

Here is my _great_ post!

.
src/pages/my-posts.astro

---
interface Frontmatter {
  title: string;
  author: string;
	description?: string;
}

import * as greatPost from '../pages/post/great-post.md';

const posts = await Astro.glob<Frontmatter>('../pages/post/*.md');
---

<p>{greatPost.frontmatter.title}</p>
<p>Written by: {greatPost.frontmatter.author}</p>

<p>Post Archive:</p>
<ul>
  {posts.map(post => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
</ul>

馃搶 Referencia
Para conocer las propiedades disponibles al importar contenido en Markdown o MDX:
Markdown & MDX

.

Content Collections

Las colecciones son una caracter铆stica de Astro que ayudan a administrar, en documentos de Markdown o MDX, el contenido de alg煤n proyecto. Las colecciones ayudan a organizar su contenido, validan su material de presentaci贸n y brindan seguridad autom谩tica de tipos de TypeScript para todo el contenido.
.

鉁 Concepto clave
Las colecciones de contenido son la mejor forma de trabajar con Markdown y MDX en cualquier proyecto de Astro.

.
Las colecciones son recursos encontrados en el subdirectorio ./src/content.
.

Desarrollo de Collections

獯 Repositorio - Coffeeroasters

猬 Commit - feat: 鉁╝dded content collection documents

猬 Commit - feat: 鉁╝dded product components

.
Como se mencion贸, las colecciones son parte fundamental de un contenido en sitios web. Su identificaci贸n se hace evidente por la dependencia e iteraci贸n visual que ser谩 servido durante la narrativa de nuestra vista o p谩gina.
.

鉁 Concepto clave
Las colecciones ser谩 de gran utilidad cuando disponemos y consumimos recursos espec铆ficos agrupados (posts-post, authors-author, products-product, etc.).

.

.
Podemos analizar 2 componentes claro que distribuye nuestra colecci贸n de productos:

  • Products Gallery - Componente para distribuir en grid nuestros productos existentes
  • Product Item - Componente que representa a un producto

.
De aqu铆, se menciona la primera estructura visual de alguna colecci贸n, lo cual ganamos administraci贸n para aislar (similar a un modelo en la arquitectura MVC).
.
Siguiendo la 馃摎 documentaci贸n, se organiza nuestras colecciones en el subdirectorio ./src/content. El cual, al lanzar nuestro proyecto en dev o build, crear谩 y sincronizar谩 un directorio llamado .astro.
.

鈩癸笍 Definici贸n
. astro es un directorio donde gestiona los tipos de las colecciones generadas por Astro, si fuera el caso sincronizarlas manualmente, por alg煤n tipo de error, corremos el comando astro sync.
Se recomienda omitirlo en el archivo .gitignore

.
Al componentizar nuestra aplicaci贸n, podemos dividir en piezas nuestros diferentes componentes (dise帽o basado en composici贸n), del cual tendr铆amos los siguientes componentes.
.
./src/componentes/Products/Item.astro

---
interface Props {
    title: string
    image: string
    content: string
}

const { title, image, content } = Astro.props
---

<div class='product-item'>
    <img src={image} alt={title} />
    <div class='product-item__body'>
        <h3>{title}</h3>
        <p>{content}</p>
    </div>
</div>

El cual ser谩 consultado y gestionado por un componente de tipo wrapper, el cual para su uso dependener谩 de las colecciones, como modelos, y el producto como plantilla de representaci贸n.
.
./src/componentes/Products/Gallery.astro

---
import { getCollection } from 'astro:content'
import Product from './Item.astro'
const products = await getCollection('products')
---

<div class='products-gallery'>
    {products.map(product => (
        <Product title={product.data.title}
                 image={product.data.image}
                 content={product.body} />
    ))}
</div>

.

鉁 Concepto clave
Las variantes visuales o de organizaci贸n de nuestros componentes, pueden estar contenida en su generalizaci贸n, como Products. Permitiendo utilizar sus diferentes presentaciones de manera selectiva, ProductsGallery y/o ProductsItem.

.
Como se observa, se consumir谩 de nuestro contenido la siguiente definici贸n de colecciones:
.
./src/content/products/danche.md

---
title: Danche
image: /images/products/danche.png
---

Ethiopian hand-harvested blend densely packed with vibrant fruit notes.

.

鉁 Concepto clave
Donde Astro nos recomienda delimiar y configurar nuestras colecciones para as铆, extender los diferentes arquetipos de nuestro producto web.

.
`./src/content/config.ts

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

export const collections = {
    products: defineCollection({
        schema: z.object({
            title: z.string(),
            image: z.string(),
        }),
    }),
}

Finalmente, lo disponemos como contenido de nuestra p谩gina en una secci贸n.
.
./src/pages/index.astro

---
import ProductsGallery from '@components/Products/Gallery.astro'
---

<Default>

        <section class='products'>
            <h2>Our premium collection</h2>
            <ProductsGallery />
        </section>

    </main>
</Default>

.

獯 Repositorio - Coffeeroasters

猬 Commit - feat: 鉁╝dded content collection documents

猬 Commit - feat: 鉁╝dded product components

.