Colecciones y campos

En esta página

Las colecciones son la base del modelo de contenido de EmDash. Cada colección representa un tipo de contenido (entradas, páginas, productos) e incluye definiciones de campos que determinan la forma de tus datos.

Crear colecciones

Crea colecciones desde el panel de administración en Tipos de contenido. Cada colección tiene:

Tipos de contenido de EmDash: páginas, entradas y colecciones personalizadas con sus funciones
PropiedadDescripción
slugIdentificador seguro para URL (p. ej. posts, products)
labelNombre visible (p. ej. «Blog Posts»)
labelSingularForma singular (p. ej. «Post»)
descriptionDescripción opcional para editoras
iconNombre de icono Lucide para la barra lateral del admin
supportsFunciones como borradores, revisiones, vista previa, programación, búsqueda, SEO

Funciones de la colección

Al crear una colección, activa las funciones que necesites:

FunciónDescripción
draftsFlujo de borrador/publicado
revisionsHistorial de contenido con instantáneas de versión
previewURLs de vista previa firmadas para borradores
schedulingProgramar publicación en una fecha futura
// Ejemplo de colección con todas las funciones
{
  slug: "posts",
  label: "Blog Posts",
  labelSingular: "Post",
  supports: ["drafts", "revisions", "preview", "scheduling"]
}

Tipos de campo

EmDash admite 15 tipos de campo que se mapean a tipos de columna SQLite:

Campos de texto

string

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 conserva la estructura sin incrustar HTML.

json

Datos JSON arbitrarios. Almacenados 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

Una opción de una lista. Se mapea a columna TEXT.

{
  slug: "status",
  type: "select",
  label: "Product Status",
  validation: {
    options: ["active", "discontinued", "coming_soon"]
  }
}

multiSelect

Varias 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 multimedia. Guarda el ID de medio como TEXT.

{ slug: "featuredImage", type: "image", label: "Featured Image" }

file

Selector de archivo de la biblioteca multimedia. Guarda el ID de medio como TEXT.

{ slug: "attachment", type: "file", label: "PDF Attachment" }

reference

Referencia a una entrada de otra colección. Guarda el ID de entrada como TEXT.

{
  slug: "author",
  type: "reference",
  label: "Author",
  options: {
    collection: "authors"
  }
}

Propiedades de campo

Cada campo admite estas propiedades:

PropiedadTipoDescripción
slugstringNombre de columna en la base de datos
labelstringEtiqueta visible en la UI del admin
typeFieldTypeUno de los 15 tipos de campo
requiredbooleanSi el campo debe tener valor
uniquebooleanSi los valores deben ser únicos entre entradas
defaultValueunknownValor por defecto para entradas nuevas
validationobjectReglas de validación específicas del tipo
widgetstringIdentificador de widget personalizado
optionsobjectConfiguración específica del widget
sortOrdernumberOrden de visualización en el editor

Reglas de validación

El objeto validation varía según el tipo de campo:

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
}

Ejemplo con validació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 la UI específico del campo:

interface FieldWidgetOptions {
	rows?: number; // text (filas del textarea)
	showPreview?: boolean; // image, file
	collection?: string; // reference (colección destino)
	allowMultiple?: boolean; // reference (varias referencias)
	[key: string]: unknown; // opciones de widget personalizado
}

Ejemplo de campo de referencia:

{
  slug: "relatedProducts",
  type: "reference",
  label: "Related Products",
  options: {
    collection: "products",
    allowMultiple: true
  }
}

Consultar colecciones

Usa las funciones de consulta incluidas para obtener contenido. Siguen el patrón de colecciones en vivo de Astro y devuelven resultados estructurados:

import { getEmDashCollection, getEmDashEntry } from "emdash";

// 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" },
});

// 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:

// .emdash/types.ts (generado)
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 en base de datos

Los tipos de campo se mapean a tipos de columna SQLite:

Tipo de campoTipo SQLiteNotas
stringTEXT
textTEXT
slugTEXT
numberREALcoma flotante 64 bits
integerINTEGERentero con signo 64 bits
booleanINTEGER0 o 1
datetimeTEXTformato ISO 8601
selectTEXT
multiSelectJSONarray de cadenas
portableTextJSONarray de bloques
imageTEXTID de medio
fileTEXTID de medio
referenceTEXTID de entrada
jsonJSONJSON arbitrario

Próximos pasos