Una colección es un tipo de contenido (publicaciones, páginas, productos). Sus definiciones de campo establecen la estructura de los datos de cada entrada.
Crear colecciones
Crea colecciones a través del panel de administración en Content Types. Cada colección tiene las siguientes propiedades:
| Propiedad | Descripción |
|---|---|
slug | Identificador seguro para URL (ej., posts, products) |
label | Nombre para mostrar (ej., “Blog Posts”) |
labelSingular | Forma singular (ej., “Post”) |
description | Descripción opcional para editores |
icon | Nombre de icono Lucide para la barra lateral del admin |
supports | Características como borradores, revisiones, vista previa, programación, búsqueda, seo |
Características de colección
Al crear una colección, habilita las características que necesites:
| Característica | Descripción |
|---|---|
drafts | Habilitar flujo de trabajo borrador/publicado |
revisions | Rastrear historial de contenido con instantáneas de versión |
preview | Generar URLs de vista previa firmadas para contenido borrador |
scheduling | Programar contenido para publicar en una fecha futura |
La siguiente colección habilita las cuatro características:
{
slug: "posts",
label: "Blog Posts",
labelSingular: "Post",
supports: ["drafts", "revisions", "preview", "scheduling"]
}
Tipos de campo
EmDash soporta 16 tipos de campo que se mapean a tipos de columna SQLite.
Campos de texto
string
Entrada de texto corto. Se mapea a columna TEXT.
{ slug: "title", type: "string", label: "Title" } text
Área de texto multilínea. Se mapea a columna TEXT.
{ slug: "excerpt", type: "text", label: "Excerpt" } slug
Campo slug seguro para URL. Se mapea a columna TEXT.
{ slug: "handle", type: "slug", label: "URL Handle" } Contenido enriquecido
portableText
Editor de texto enriquecido (TipTap/ProseMirror). Almacenado como JSON.
{ slug: "content", type: "portableText", label: "Content" }Portable Text es un formato basado en bloques que preserva la estructura sin incrustar HTML.
json
Datos JSON arbitrarios. Almacenado como JSON.
{ slug: "metadata", type: "json", label: "Custom Metadata" } Números
number
Números decimales. Se mapea a columna REAL.
{ slug: "price", type: "number", label: "Price" } integer
Números enteros. Se mapea a columna INTEGER.
{ slug: "quantity", type: "integer", label: "Stock Quantity" } Booleanos y fechas
boolean
Interruptor verdadero/falso. Se mapea a INTEGER (0/1).
{ slug: "featured", type: "boolean", label: "Featured Post" } datetime
Selector de fecha y hora. Almacenado como cadena ISO 8601.
{ slug: "eventDate", type: "datetime", label: "Event Date" } Selección
select
Opción única de una lista. Se mapea a columna TEXT.
{
slug: "status",
type: "select",
label: "Product Status",
validation: {
options: ["active", "discontinued", "coming_soon"]
}
} multiSelect
Múltiples opciones de una lista. Almacenado como array JSON.
{
slug: "features",
type: "multiSelect",
label: "Product Features",
validation: {
options: ["wireless", "waterproof", "eco-friendly"]
}
} Medios y referencias
image
Selector de imagen de la biblioteca de medios. Almacena ID de medio como TEXT.
{ slug: "featuredImage", type: "image", label: "Featured Image" } file
Selector de archivo de la biblioteca de medios. Almacena ID de medio como TEXT.
{ slug: "attachment", type: "file", label: "PDF Attachment" } reference
Referencia a la entrada de otra colección. Almacena ID de entrada como TEXT.
{
slug: "author",
type: "reference",
label: "Author",
options: {
collection: "authors"
}
} Propiedades de campo
Cada campo soporta estas propiedades:
| Propiedad | Tipo | Descripción |
|---|---|---|
slug | string | Nombre de columna en la base de datos |
label | string | Etiqueta de visualización en la UI de admin |
type | FieldType | Uno de los 16 tipos de campo |
required | boolean | Si el campo debe tener un valor |
unique | boolean | Si los valores deben ser únicos entre entradas |
indexed | boolean | Permitir ordenamiento y filtrado eficiente por este campo |
defaultValue | unknown | Valor predeterminado para nuevas entradas |
validation | object | Reglas de validación específicas del tipo |
widget | string | Identificador de widget personalizado |
options | object | Configuración específica del widget |
sortOrder | number | Orden de visualización en el editor |
Establece indexed: true cuando una consulta de colección necesite usar un campo personalizado en orderBy o un filtro de campo. Los índices son compatibles con campos string, url, number, integer, boolean, datetime, select, reference y slug. EmDash rechaza campos JSON indexados, contenido enriquecido y otros tipos de campo no escalares.
Reglas de validación
El objeto validation varía según el tipo de campo. Su forma completa es:
interface FieldValidation {
required?: boolean; // Todos los tipos
min?: number; // number, integer
max?: number; // number, integer
minLength?: number; // string, text
maxLength?: number; // string, text
pattern?: string; // string (regex)
options?: string[]; // select, multiSelect
}
El siguiente campo requiere una dirección de correo electrónico única y validada por patrón:
{
slug: "email",
type: "string",
label: "Email Address",
required: true,
unique: true,
validation: {
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
}
}
Opciones de widget
El objeto options configura el comportamiento de UI específico del campo. Su forma completa es:
interface FieldWidgetOptions {
rows?: number; // text (filas del área de texto)
showPreview?: boolean; // image, file
collection?: string; // reference (colección destino)
allowMultiple?: boolean; // reference (múltiples refs)
[key: string]: unknown; // Opciones de widget personalizadas
}
El siguiente campo de referencia enlaza a múltiples productos:
{
slug: "relatedProducts",
type: "reference",
label: "Related Products",
options: {
collection: "products",
allowMultiple: true
}
}
Consultar colecciones
Usa las funciones de consulta proporcionadas para obtener contenido. Estas siguen el patrón de colecciones en vivo de Astro, devolviendo resultados estructurados. El siguiente ejemplo muestra las opciones de consulta comunes:
import { getEmDashCollection, getEmDashEntry } from "emdash";
// Obtener todas las entradas - devuelve { entries, error }
const { entries: posts } = await getEmDashCollection("posts");
// Filtrar por estado
const { entries: drafts } = await getEmDashCollection("posts", {
status: "draft",
});
// Limitar resultados
const { entries: recent } = await getEmDashCollection("posts", {
limit: 5,
});
// Filtrar por taxonomía
const { entries: newsPosts } = await getEmDashCollection("posts", {
where: { category: "news" },
});
// Obtener una entrada por slug - devuelve { entry, error, isPreview }
const { entry: post } = await getEmDashEntry("posts", "my-post-slug");
// Manejo de errores
const { entries, error } = await getEmDashCollection("posts");
if (error) {
console.error("Failed to load posts:", error);
}
Generación de tipos
Ejecuta npx emdash types para generar tipos TypeScript desde tu esquema. El archivo generado contiene una interfaz por colección:
export interface Post {
title: string;
content: PortableTextBlock[];
excerpt?: string;
featuredImage?: string;
author: string; // ID de referencia
}
export interface Product {
title: string;
price: number;
description: PortableTextBlock[];
}
Mapeo de base de datos
Los tipos de campo se mapean a tipos de columna SQLite de la siguiente manera:
| Tipo de campo | Tipo SQLite | Notas |
|---|---|---|
string | TEXT | |
text | TEXT | |
slug | TEXT | |
url | TEXT | |
number | REAL | Punto flotante de 64 bits |
integer | INTEGER | Entero con signo de 64 bits |
boolean | INTEGER | 0 o 1 |
datetime | TEXT | Formato ISO 8601 |
select | TEXT | |
multiSelect | JSON | Array de strings |
portableText | JSON | Array de bloques |
image | TEXT | ID de medio |
file | TEXT | ID de medio |
reference | TEXT | ID de entrada |
json | JSON | JSON arbitrario |
repeater | JSON | Array de subcampos |
Próximos pasos
Modelo de contenido
Comprende el modelo de contenido.
Taxonomías
Organiza contenido con categorías y etiquetas.
Biblioteca de medios
Gestiona imágenes y archivos.