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ón | Propósito | Retorna |
|---|---|---|
getEmDashCollection | Recuperar todas las entradas de un tipo de contenido | { entries, error } |
getEmDashEntry | Recuperar 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
- Crear un blog - Construir un blog completo
- Taxonomías - Filtrar por categorías y etiquetas
- Trabajar con contenido - Operaciones CRUD de administrador
- Internacionalización - Contenido multilingüe y traducciones