Consultar contenido
EmDash proporciona funciones de consulta para recuperar contenido en tus 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
Sección titulada «Funciones de consulta»EmDash exporta dos funciones de consulta principales:
| Función | Propósito | Devuelve |
|---|---|---|
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órtalas desde emdash:
import { getEmDashCollection, getEmDashEntry } from "emdash";Obtener todas las entradas
Sección titulada «Obtener todas las entradas»Usa 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 las entradas:", error);}---
<ul> {posts.map((post) => ( <li>{post.data.title}</li> ))}</ul>Filtrar por idioma
Sección titulada «Filtrar por idioma»Cuando la i18n está habilitada, filtra por idioma para recuperar contenido en un idioma específico:
// Entradas en francésconst { entries: frenchPosts } = await getEmDashCollection("posts", { locale: "fr", status: "published",});
// Usa el idioma actual de la solicitudconst { entries: localizedPosts } = await getEmDashCollection("posts", { locale: Astro.currentLocale, status: "published",});Para entradas individuales, pasa locale como tercer argumento:
const { entry: post } = await getEmDashEntry("posts", "my-post", { locale: Astro.currentLocale,});Cuando se omite locale, por defecto se usa el idioma actual de la solicitud. Si no existe una traducción para el idioma solicitado, se sigue la cadena de respaldo.
Filtrar por Estado
Sección titulada «Filtrar por Estado»Recupera solo contenido publicado o borrador:
// Solo entradas publicadasconst { entries: published } = await getEmDashCollection("posts", { status: "published",});
// Solo borradoresconst { entries: drafts } = await getEmDashCollection("posts", { status: "draft",});Limitar Resultados
Sección titulada «Limitar Resultados»Restringe el número de entradas devueltas:
// Obtener las 5 entradas más recientesconst { entries: recentPosts } = await getEmDashCollection("posts", { status: "published", limit: 5,});Filtrar por Taxonomía
Sección titulada «Filtrar por Taxonomía»Filtra entradas por categoría, etiqueta o términos de taxonomía personalizados:
// Entradas de 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érminosconst { 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
Sección titulada «Manejo de errores»Siempre verifica si hay errores cuando la fiabilidad es importante:
const { entries: posts, error } = await getEmDashCollection("posts");
if (error) { // Registrar y manejar con gracia console.error("Error al cargar las publicaciones:", error); return new Response("Error del servidor", { status: 500 });}Obtener una entrada única
Sección titulada «Obtener una entrada única»Usa 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 la entrada
Sección titulada «Tipo de retorno de la entrada»getEmDashEntry devuelve un objeto de resultado:
interface EntryResult<T> { entry: ContentEntry<T> | null; // null if not found error?: Error; // Only set for actual errors (not "not found") isPreview: boolean; // true if viewing preview/draft content}
interface ContentEntry<T> { id: string; data: T; edit: EditProxy; // Visual editing annotations}El objeto data dentro de entry contiene todos los campos definidos para el tipo de contenido. El proxy edit proporciona anotaciones para edición visual (ver más abajo).
Modo de vista previa
Sección titulada «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. Tus funciones de consulta luego sirven contenido en borrador sin ningún parámetro especial:
---import { getEmDashEntry } from "emdash";
const { slug } = Astro.params;
// No se necesita manejo especial de vista previa — el middleware lo hace automáticamenteconst { 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"> Estás viendo una vista previa. Este contenido aún no está publicado. </div>)}
<article> <h1>{entry.data.title}</h1> <PortableText value={entry.data.content} /></article>Edición visual
Sección titulada «Edición visual»Cada entrada devuelta por las funciones de consulta incluye un proxy edit para anotar tus plantillas. Extiéndelo en los 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, la extensión del proxy no produce salida — costo de ejecución cero.
Ordenar resultados
Sección titulada «Ordenar resultados»getEmDashCollection no garantiza un orden. Ordena los resultados en tu plantilla:
const { entries: posts } = await getEmDashCollection("posts", { status: "published",});
// Ordenar por fecha de publicación, los más nuevos primeroconst sorted = posts.sort( (a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0),);Patrones de orden habituales
Sección titulada «Patrones de orden habituales»// Orden alfabético por títuloposts.sort((a, b) => a.data.title.localeCompare(b.data.title));
// Por campo de orden personalizadoposts.sort((a, b) => (a.data.order ?? 0) - (b.data.order ?? 0));
// Orden aleatorioposts.sort(() => Math.random() - 0.5);Tipos de TypeScript
Sección titulada «Tipos de TypeScript»Genera tipos de TypeScript para tus colecciones:
npx emdash typesEsto crea .emdash/types.ts con interfaces para cada colección. Úsalas para seguridad de tipos:
import { getEmDashCollection, getEmDashEntry } from "emdash";import type { Post } from "../../.emdash/types";
// Consulta de colección con seguridad de tiposconst { entries: posts } = await getEmDashCollection<Post>("posts");// posts es ContentEntry<Post>[]
// Consulta de entrada con seguridad de tiposconst { entry: post } = await getEmDashEntry<Post>("posts", "my-post");// post es ContentEntry<Post> | nullRenderizado estático vs. en el servidor
Sección titulada «Renderizado estático vs. en el servidor»El contenido de EmDash funciona tanto con páginas estáticas como renderizadas en el servidor.
Estático (Pre-renderizado)
Sección titulada «Estático (Pre-renderizado)»Para páginas estáticas, usa 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 el servidor
Sección titulada «Renderizado en el servidor»Para páginas renderizadas en el servidor, consulta 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
Sección titulada «Consideraciones de Rendimiento»Almacenamiento en Caché
Sección titulada «Almacenamiento en Caché»EmDash utiliza las colecciones de contenido en vivo de Astro, que manejan el almacenamiento en caché automáticamente. Para páginas renderizadas en el servidor, considera agregar encabezados de caché HTTP:
---const { entries: posts } = await getEmDashCollection("posts", { status: "published",});
// Cachear durante 5 minutosAstro.response.headers.set("Cache-Control", "public, max-age=300");---Evitar Consultas Redundantes
Sección titulada «Evitar Consultas Redundantes»Consulta una vez y pasa los datos a los componentes:
---import { getEmDashCollection } from "emdash";import PostList from "../../components/PostList.astro";import Sidebar from "../../components/Sidebar.astro";
// Consultar una vezconst { 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
Sección titulada «Próximos Pasos»- Crear un Blog - Construye un blog completo
- Taxonomías - Filtrar por categorías y etiquetas
- Trabajar con Contenido - Operaciones CRUD de administración
- Internacionalización - Contenido multilingüe y traducciones