Consultar contenido

En esta página

EmDash proporciona funciones de consulta para recuperar contenido en sus páginas y componentes de Astro. Estas funciones siguen el patrón de colecciones de contenido en vivo de Astro, devolviendo resultados estructurados con manejo de errores.

Funciones de consulta

EmDash exporta dos funciones de consulta principales:

FunciónPropósitoRetorna
getEmDashCollectionRecuperar todas las entradas de un tipo de contenido{ entries, error }
getEmDashEntryRecuperar una sola entrada por ID o slug{ entry, error, isPreview }

Impórtelas desde emdash:

import { getEmDashCollection, getEmDashEntry } from "emdash";

Obtener todas las entradas

Use getEmDashCollection para recuperar todas las entradas de un tipo de contenido:

---
import { getEmDashCollection } from "emdash";

const { entries: posts, error } = await getEmDashCollection("posts");

if (error) {
  console.error("Error al cargar publicaciones:", error);
}
---

<ul>
  {posts.map((post) => (
    <li>{post.data.title}</li>
  ))}
</ul>

Filtrar por idioma

Cuando i18n está habilitado, filtre por idioma para recuperar contenido en un idioma específico:

// Publicaciones en francés
const { entries: frenchPosts } = await getEmDashCollection("posts", {
	locale: "fr",
	status: "published",
});

// Usar el idioma de la solicitud actual
const { entries: localizedPosts } = await getEmDashCollection("posts", {
	locale: Astro.currentLocale,
	status: "published",
});

Para entradas individuales, pase locale como tercer argumento:

const { entry: post } = await getEmDashEntry("posts", "my-post", {
	locale: Astro.currentLocale,
});

Cuando se omite locale, por defecto usa el idioma actual de la solicitud. Si no existe traducción para el idioma solicitado, se sigue la cadena de respaldo.

Filtrar por estado

Recuperar solo contenido publicado o borrador:

// Solo publicaciones publicadas
const { entries: published } = await getEmDashCollection("posts", {
	status: "published",
});

// Solo borradores
const { entries: drafts } = await getEmDashCollection("posts", {
	status: "draft",
});

Limitar resultados

Restrinja el número de entradas devueltas:

// Obtener las 5 publicaciones más recientes
const { entries: recentPosts } = await getEmDashCollection("posts", {
	status: "published",
	limit: 5,
});

Filtrar por taxonomía

Filtre entradas por categoría, etiqueta o términos de taxonomía personalizados:

// Publicaciones en la categoría "news"
const { entries: newsPosts } = await getEmDashCollection("posts", {
	status: "published",
	where: { category: "news" },
});

// Publicaciones con la etiqueta "javascript"
const { entries: jsPosts } = await getEmDashCollection("posts", {
	status: "published",
	where: { tag: "javascript" },
});

// Publicaciones que coinciden con cualquiera de múltiples términos
const { entries: featuredNews } = await getEmDashCollection("posts", {
	status: "published",
	where: { category: ["news", "featured"] },
});

El filtro where usa lógica OR cuando se proporcionan múltiples valores para una sola taxonomía.

Manejo de errores

Siempre verifique errores cuando la confiabilidad es importante:

const { entries: posts, error } = await getEmDashCollection("posts");

if (error) {
	// Registrar y manejar elegantemente
	console.error("Error al cargar publicaciones:", error);
	return new Response("Error del servidor", { status: 500 });
}

Obtener una sola entrada

Use getEmDashEntry para recuperar una entrada por su ID o slug:

---
import { getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";

const { slug } = Astro.params;
const { entry: post, error } = await getEmDashEntry("posts", slug);

if (error) {
  return new Response("Error del servidor", { status: 500 });
}

if (!post) {
  return Astro.redirect("/404");
}
---

<article>
  <h1>{post.data.title}</h1>
  <PortableText value={post.data.content} />
</article>

Tipo de retorno de entrada

getEmDashEntry devuelve un objeto de resultado:

interface EntryResult<T> {
	entry: ContentEntry<T> | null; // null si no se encuentra
	error?: Error; // Solo establecido para errores reales (no "no encontrado")
	isPreview: boolean; // true si se visualiza contenido de vista previa/borrador
}

interface ContentEntry<T> {
	id: string;
	data: T;
	edit: EditProxy; // Anotaciones de edición visual
}

El objeto data dentro de entry contiene todos los campos definidos para el tipo de contenido. El proxy edit proporciona anotaciones de edición visual (ver abajo).

Modo de vista previa

EmDash maneja la vista previa automáticamente a través de middleware. Cuando una URL contiene un token _preview válido, el middleware lo verifica y configura el contexto de la solicitud. Sus funciones de consulta luego sirven contenido borrador sin parámetros especiales:

---
import { getEmDashEntry } from "emdash";

const { slug } = Astro.params;

// No se necesita manejo especial de vista previa — el middleware lo hace automáticamente
const { entry, isPreview, error } = await getEmDashEntry("posts", slug);

if (error) {
  return new Response("Error del servidor", { status: 500 });
}

if (!entry) {
  return Astro.redirect("/404");
}
---

{isPreview && (
  <div class="preview-banner">
    Viendo vista previa. Este contenido no está publicado.
  </div>
)}

<article>
  <h1>{entry.data.title}</h1>
  <PortableText value={entry.data.content} />
</article>

Edición visual

Cada entrada devuelta por funciones de consulta incluye un proxy edit para anotar sus plantillas. Expándalo en elementos para habilitar la edición en línea para editores autenticados:

<article {...entry.edit}>
  <h1 {...entry.edit.title}>{entry.data.title}</h1>
  <div {...entry.edit.content}>
    <PortableText value={entry.data.content} />
  </div>
</article>

En modo de edición, {...entry.edit.title} produce un atributo data-emdash-ref que la barra de herramientas de edición visual usa para habilitar la edición en línea. En producción, las expansiones del proxy no producen salida.

Ordenar resultados

getEmDashCollection no garantiza un orden de clasificación. Ordene los resultados en su plantilla:

const { entries: posts } = await getEmDashCollection("posts", {
	status: "published",
});

// Ordenar por fecha de publicación, más reciente primero
const sorted = posts.sort(
	(a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0),
);

Patrones de ordenamiento comunes

// Alfabéticamente por título
posts.sort((a, b) => a.data.title.localeCompare(b.data.title));

// Por campo de orden personalizado
posts.sort((a, b) => (a.data.order ?? 0) - (b.data.order ?? 0));

// Orden aleatorio
posts.sort(() => Math.random() - 0.5);

Tipos TypeScript

Genere tipos TypeScript para sus colecciones:

npx emdash types

Esto crea .emdash/types.ts con interfaces para cada colección. Úselas para seguridad de tipos:

import { getEmDashCollection, getEmDashEntry } from "emdash";
import type { Post } from "../.emdash/types";

// Consulta de colección con seguridad de tipos
const { entries: posts } = await getEmDashCollection<Post>("posts");
// posts es ContentEntry<Post>[]

// Consulta de entrada con seguridad de tipos
const { entry: post } = await getEmDashEntry<Post>("posts", "my-post");
// post es ContentEntry<Post> | null

Renderizado estático vs. servidor

El contenido de EmDash funciona tanto con páginas estáticas como renderizadas en el servidor.

Estático (Pre-renderizado)

Para páginas estáticas, use getStaticPaths para generar rutas en tiempo de compilación:

---
import { getEmDashCollection, getEmDashEntry } from "emdash";

export async function getStaticPaths() {
  const { entries: posts } = await getEmDashCollection("posts", {
    status: "published",
  });

  return posts.map((post) => ({
    params: { slug: post.data.slug },
  }));
}

const { slug } = Astro.params;
const { entry: post } = await getEmDashEntry("posts", slug);
---

Renderizado en servidor

Para páginas renderizadas en el servidor, consulte el contenido directamente:

---
export const prerender = false;

import { getEmDashEntry } from "emdash";

const { slug } = Astro.params;
const { entry: post, error } = await getEmDashEntry("posts", slug);

if (error) {
  return new Response("Error del servidor", { status: 500 });
}

if (!post) {
  return new Response(null, { status: 404 });
}
---

Consideraciones de rendimiento

Caché

EmDash usa colecciones de contenido en vivo de Astro, que manejan el almacenamiento en caché automáticamente. Para páginas renderizadas en el servidor, considere agregar encabezados de caché HTTP:

---
const { entries: posts } = await getEmDashCollection("posts", {
  status: "published",
});

// Almacenar en caché durante 5 minutos
Astro.response.headers.set("Cache-Control", "public, max-age=300");
---

Evitar consultas redundantes

Consulte una vez y pase datos a componentes:

---
import { getEmDashCollection } from "emdash";
import PostList from "../components/PostList.astro";
import Sidebar from "../components/Sidebar.astro";

// Consultar una vez
const { entries: posts } = await getEmDashCollection("posts", {
  status: "published",
});

const featured = posts.filter((p) => p.data.featured);
const recent = posts.slice(0, 5);
---

<PostList posts={featured} />
<Sidebar posts={recent} />

Próximos pasos