Referencia de tipos de campo

En esta página

EmDash admite 17 tipos de campo para definir esquemas de contenido. Cada tipo se asigna a un tipo de columna SQLite y proporciona la IU de administración adecuada.

Resumen

La siguiente tabla enumera cada tipo de campo y su columna SQLite:

TypeSQLite ColumnDescription
stringTEXTEntrada de texto corto
textTEXTTexto multilínea
urlTEXTValor URL
numberREALNúmero decimal
integerINTEGERNúmero entero
booleanINTEGERVerdadero/falso
datetimeTEXTFecha y hora
selectTEXTElección única entre opciones
multiSelectJSONElecciones múltiples
portableTextJSONContenido de texto enriquecido
imageTEXTReferencia de imagen
fileTEXTReferencia de archivo
referencenoneEnlaza entradas de otra colección
jsonJSONDatos JSON arbitrarios
slugTEXTIdentificador seguro para URL
repeaterJSONGrupo de campos repetible
blocksJSONComposición de página tipada

Tipos de texto

string

Texto corto de una sola línea. Úselo para títulos, nombres y valores breves.

{
  slug: "title",
  label: "Title",
  type: "string",
  required: true,
  validation: {
    minLength: 1,
    maxLength: 200,
  },
}

Opciones de validación:

  • minLength — Número mínimo de caracteres
  • maxLength — Número máximo de caracteres
  • pattern — Expresión regular que el valor debe cumplir

El editor limita la entrada a maxLength y muestra un contador de caracteres en vivo frente a las reglas de longitud.

Opciones del widget:

  • Ninguna específica

text

Texto plano multilínea. Úselo para descripciones, extractos y texto plano más largo.

{
  slug: "excerpt",
  label: "Excerpt",
  type: "text",
  options: {
    rows: 3,
  },
}

Opciones de validación:

  • minLength — Número mínimo de caracteres
  • maxLength — Número máximo de caracteres
  • pattern — Expresión regular que el valor debe cumplir

El editor limita la entrada a maxLength y muestra un contador de caracteres en vivo frente a las reglas de longitud.

Opciones del widget:

  • rows — Número de filas en el textarea (predeterminado: 3)

url

Una dirección web. La API de contenido rechaza valores que no son URL válidas.

{
  slug: "website",
  label: "Website",
  type: "url",
  required: true,
}

Los campos URL se almacenan como texto. Use un campo string en su lugar cuando el valor pueda ser una ruta relativa como /about, porque las rutas relativas no son valores válidos para un campo url.

slug

Texto destinado a contener un valor similar a un slug. Este tipo de campo personalizado no genera ni sanea su valor.

{
  slug: "legacy_slug",
  label: "Legacy Slug",
  type: "slug",
  required: true,
  unique: true,
}

Cada entrada de contenido ya tiene un slug de sistema reservado, que EmDash gestiona por separado para las URL públicas. Use un campo slug personalizado solo cuando el modelo de contenido necesite otro valor similar a un slug almacenado.

Tipos numéricos

number

Número decimal. Úselo para precios, valoraciones y medidas.

{
  slug: "price",
  label: "Price",
  type: "number",
  required: true,
  validation: {
    min: 0,
    max: 999999.99,
  },
}

Opciones de validación:

  • min — Valor mínimo
  • max — Valor máximo

El editor establece min y max en la entrada numérica y muestra el rango permitido debajo.

Almacenado como SQLite REAL (punto flotante de 64 bits).

integer

Número entero. Úselo para cantidades, contadores y valores de orden.

{
  slug: "quantity",
  label: "Quantity",
  type: "integer",
  defaultValue: 1,
  validation: {
    min: 0,
    max: 1000,
  },
}

Opciones de validación:

  • min — Valor mínimo
  • max — Valor máximo

El editor establece min y max en la entrada numérica y muestra el rango permitido debajo.

Almacenado como SQLite INTEGER.

boolean

Verdadero o falso. Úselo para interruptores y flags.

{
  slug: "featured",
  label: "Featured",
  type: "boolean",
  defaultValue: false,
}

Almacenado como SQLite INTEGER (0 o 1).

Fecha y hora

datetime

Un instante en el tiempo. Las escrituras de API, MCP y CLI deben incluir Z o un desplazamiento UTC explícito. La administración interpreta su selector de fecha y hora en la zona horaria configurada en Settings → General.

{
  slug: "publishedAt",
  label: "Published At",
  type: "datetime",
}

Formato de almacenamiento: 2025-01-24T12:00:00.000Z

EmDash convierte la entrada aceptada a UTC con milisegundos de tres dígitos antes de almacenarla. Por ejemplo, 2025-01-24T21:00:00+09:00 se almacena como 2025-01-24T12:00:00.000Z. Use un campo string en su lugar cuando el valor sea una fecha de calendario o una hora local de reloj de pared en lugar de un instante.

Tipos de selección

select

Selección única entre opciones predefinidas.

{
  slug: "status",
  label: "Status",
  type: "select",
  required: true,
  defaultValue: "draft",
  validation: {
    options: ["draft", "published", "archived"],
  },
}

Opciones de validación:

  • options — Array opcional de valores permitidos. Proporciónelo para presentar opciones predefinidas y rechazar otras cadenas; sin él, la validación acepta cualquier cadena.

Almacenado como TEXT que contiene el valor seleccionado.

multiSelect

Selecciones múltiples entre opciones predefinidas.

{
  slug: "tags",
  label: "Tags",
  type: "multiSelect",
  validation: {
    options: ["news", "tutorial", "review", "opinion"],
  },
}

Opciones de validación:

  • options — Array opcional de valores permitidos. Proporciónelo para presentar opciones predefinidas y rechazar otras cadenas; sin él, la validación acepta cualquier array de cadenas.

Almacenado como array JSON: ["news", "tutorial"]

Contenido enriquecido

portableText

Contenido de texto enriquecido en formato Portable Text. Admite encabezados, listas, enlaces, imágenes y bloques personalizados.

{
  slug: "content",
  label: "Content",
  type: "portableText",
  required: true,
}

El valor se almacena como un array JSON de bloques Portable Text, por ejemplo:

[
	{
		"_type": "block",
		"style": "normal",
		"children": [{ "_type": "span", "text": "Hello world" }]
	}
]

Los plugins pueden añadir tipos de bloque personalizados (embeds, widgets, etc.) al editor. Aparecen en el menú de comandos slash. Renderizar el bloque guardado en el sitio público requiere un componente Astro de un plugin nativo o paquete companion. Consulte Componentes de renderizado de Portable Text.

Tipos de medios

image

Referencia a una imagen subida. Incluye metadatos como dimensiones y texto alternativo.

{
  slug: "featuredImage",
  label: "Featured Image",
  type: "image",
  validation: {
    allowedMimeTypes: ["image/jpeg", "image/png"],
  },
  options: {
    darkVariant: true,
  },
}

Opciones del widget:

  • darkVariant — Ofrece a los editores un segundo espacio para una imagen mostrada en esquemas de color oscuros (predeterminado: false). Consulte Dark Mode.

Opciones de validación:

  • allowedMimeTypes — Lista no vacía de tipos MIME exactos aceptados para el medio seleccionado

El valor se almacena como un objeto con la referencia de medios y sus metadatos:

{
	"id": "01HXK5MZSN...",
	"src": "/_emdash/api/media/file/01HXK5MZSN...",
	"alt": "Description",
	"width": 1920,
	"height": 1080,
	"provider": "local",
	"meta": {
		"storageKey": "01HXK5MZSN....jpg"
	}
}

Con darkVariant habilitado, el valor puede llevar la contraparte oscura bajo darkVariant, con la misma forma:

{
	"id": "01HXK5MZSN...",
	"alt": "Architecture diagram",
	"width": 1920,
	"height": 1080,
	"darkVariant": {
		"id": "01HXK5N2QT...",
		"width": 1920,
		"height": 1080
	}
}

file

Referencia a un archivo subido como un documento o PDF.

{
  slug: "document",
  label: "Document",
  type: "file",
  validation: {
    allowedMimeTypes: ["application/pdf"],
  },
}

Opciones de validación:

  • allowedMimeTypes — Lista no vacía de tipos MIME exactos aceptados para el medio seleccionado

El valor se almacena como una referencia de proveedor con metadatos en caché:

{
	"id": "01HXK5MZSN...",
	"provider": "local",
	"filename": "report.pdf",
	"mimeType": "application/pdf",
	"meta": {
		"storageKey": "01HXK5MZSN....pdf"
	}
}

url y size, como los demás campos de metadatos en caché, son opcionales. Las consultas de contenido devuelven el valor persistido tal cual y no lo hidratan desde la biblioteca de medios. Consulte Valores de archivo y metadatos actuales para las APIs de consulta canónicas cuando necesite metadatos frescos o una URL específica del proveedor.

Tipos relacionales

reference

Enlaza una entrada con entradas de otra colección y se muestra como un selector de entradas en la administración. Sus enlaces pertenecen a una relación: un objeto de esquema que une dos colecciones, nombra cada lado y limita cuántas entradas puede enlazar cada lado. Relations cubre el flujo de trabajo del editor y la administración.

El siguiente campo enlaza una publicación con una entrada de la colección authors:

{
  slug: "author",
  label: "Author",
  type: "reference",
  required: true,
  validation: {
    targetCollection: "authors",
    multiple: false,
  },
}

Validación:

  • targetCollection — Slug de la colección a la que enlaza este campo. Crear el campo crea una relación para él.
  • multiple — Permitir más de una entrada enlazada (predeterminado: false). Léalo solo junto con targetCollection, porque el límite pertenece entonces a la nueva relación.
  • relation — Slug de una relación existente a la que vincularse en lugar de crear una.
  • relationSide — En qué extremo de relation se sitúa esta colección, "parent" o "child". Establézcalo solo para una relación cuyos dos extremos sean la misma colección, donde ambos extremos coinciden.

Indique targetCollection o relation. Un campo creado desde targetCollection se convierte en el extremo padre de una relación llamada {collection}_{field}, cuyo lado hijo toma la etiqueta del campo y mantiene una entrada a menos que se establezca multiple. Un campo creado desde relation ve esa relación desde el extremo en el que se sitúa su colección, y la colección del otro extremo es el destino del campo. Una relación acepta un campo por extremo, por lo que se rechaza un segundo campo sobre el mismo extremo. Ambas formas almacenan relation, relationSide y targetCollection en el campo creado, y la colección destino queda fija a partir de entonces: para cambiarla, elimine el campo y añada uno nuevo. Renombrar el campo renombra el lado de la relación que ve.

Un campo de referencia no añade ninguna columna a la tabla de la colección. Sus enlaces viven en _emdash_content_references, indexados por el grupo de traducción de cada entrada, de modo que una selección se comparte entre las traducciones de una entrada en lugar de establecerse por locale. Las lecturas de contenido devuelven las entradas enlazadas bajo references, indexadas por el slug del campo, en lugar de en data. En una plantilla, pida el campo por nombre — consulte Leer campos de referencia.

Un campo vinculado a una relación no puede establecer indexed, porque no almacena ninguna columna que indexar, y la búsqueda del sitio no lo cubre.

Campos sin relación

Un campo de referencia que no nombra ni una relación ni una colección destino conserva una columna TEXT y guarda en ella un ID de entrada:

"01HXK5MZSN..."

Un campo cuyo options.allowMultiple está establecido guarda un array JSON de IDs de entrada en la misma columna:

["01HXK5MZSN...", "01HXK6NATS..."]

La columna se lee y escribe como cualquier otra columna de texto, el esquema de la colección valida el valor como cadena, y el campo puede establecer indexed y actuar como filtro de lista de contenido. Se muestra como un cuadro de texto en lugar de un selector.

Para convertirlo en un selector, abra el campo en Content Types y elija una colección referenciada. EmDash crea la relación, copia los IDs de entrada de la columna como enlaces y borra los flags searchable e indexed del campo, de modo que los filtros de lista de contenido y la búsqueda del sitio dejan de cubrirlo. La columna permanece en su lugar y deja de escribirse. Relations cubre el mismo paso desde el lado del editor.

Un sitio actualizado desde una versión anterior puede conservar campos en este estado. Consulte Los campos de referencia se vinculan a relaciones para lo que la actualización vincula y lo que deja para que usted vincule.

Tipos flexibles

json

Datos JSON arbitrarios. Úselo para estructuras anidadas complejas, integraciones de terceros o datos sin un esquema fijo.

{
  slug: "metadata",
  label: "Metadata",
  type: "json",
}

Almacenado tal cual en una columna JSON de SQLite.

repeater

Una lista repetible de filas estructuradas. Defina al menos un subcampo en validation.subFields; los editores pueden entonces añadir, eliminar, reordenar y editar filas sin introducir JSON en bruto.

El siguiente campo almacena una lista de especificaciones de producto:

{
  slug: "specifications",
  label: "Specifications",
  type: "repeater",
  validation: {
    minItems: 1,
    maxItems: 12,
    subFields: [
      { slug: "label", label: "Label", type: "string", required: true },
      { slug: "value", label: "Value", type: "text", required: true },
      { slug: "source", label: "Source", type: "url" },
    ],
  },
}

Los valores de repeater se almacenan como un array de objetos:

[
	{
		"label": "Weight",
		"value": "1.2 kg",
		"source": "https://example.com/specifications"
	}
]

Los tipos de subcampo permitidos son string, text, url, number, integer, boolean, datetime, select e image. Los repeaters no pueden contener otro repeater ni un campo complejo como portableText, reference o file.

La validación de repeater acepta estas propiedades:

  • subFields — Una o más definiciones de subcampo. Cada definición requiere slug, label y type; también puede establecer required. Un subcampo select suministra sus opciones mediante options.
  • minItems — Número mínimo de filas. Debe ser cero o mayor.
  • maxItems — Número máximo de filas. Debe ser uno o mayor y no puede ser menor que minItems.

blocks

Una lista ordenada de bloques de contenido tipados. Cada tipo de bloque tiene sus propios campos y conserva versiones numeradas. Defina los tipos de bloque mediante la API de esquema, MCP o un archivo seed antes de añadirlos a un campo de colección.

El siguiente campo permite a los editores componer una página a partir de bloques hero y call-to-action:

{
  slug: "layout",
  label: "Layout",
  type: "blocks",
  validation: {
    allowedTypes: ["hero", "call_to_action"],
    maxItems: 20,
  },
}

Cada bloque almacenado lleva su tipo, versión y clave estable junto a los campos declarados por esa versión:

[
	{
		"_type": "hero",
		"_version": 1,
		"_key": "01K5AB3F7M9QZ2X8W4V6T1R0YH",
		"heading": "Bread made slowly, by hand."
	}
]

La validación de blocks acepta estas propiedades:

  • allowedTypes — Slugs de tipos de bloque ordenados disponibles para bloques nuevos.
  • retiredTypes — Tipos de bloque gestionados por el servidor retenidos para el contenido almacenado pero no disponibles para bloques nuevos.
  • minItems — Número mínimo de bloques. Elevarlo por encima de cero en una colección poblada requiere una migración de contenido.
  • maxItems — Número máximo de bloques, hasta 100.

Un campo blocks es opcional y por defecto es un array vacío. No puede ser required, unique, searchable, indexed ni renderizado por un widget de campo personalizado. Las definiciones de bloque pueden usar campos escalares, de texto, de selección, Portable Text, imagen, archivo y repeater. No pueden contener referencias, JSON, slugs ni blocks anidados.

Renderice el array almacenado con <Blocks value components fallback> de emdash/ui. Consulte Crear páginas con blocks para ejemplos de seed, mapa de componentes, renderer ausente, activación y migración.

Propiedades de campo

Todos los campos admiten estas propiedades comunes:

PropertyTypeDescription
slugstringIdentificador único (obligatorio)
labelstringNombre para mostrar (obligatorio)
typeFieldTypeTipo de campo (obligatorio)
requiredbooleanExigir un valor (predeterminado: false)
uniquebooleanExigir unicidad (predeterminado: false)
searchablebooleanIncluir el campo en la búsqueda de texto completo (predeterminado: false)
indexedbooleanHabilitar ordenación/filtrado indexado
translatablebooleanAlmacenar un valor por locale (predeterminado: true)
defaultValueunknownValor predeterminado para entradas nuevas
validationobjectReglas de validación específicas del tipo
widgetstringAnulación de widget personalizado
optionsobjectConfiguración del widget
sortOrdernumberOrden de visualización en la administración

indexed está disponible para campos escalares: string, url, number, integer, boolean, datetime, select, reference y slug. Un campo indexado puede pasarse como el campo orderBy o usarse en fieldFilters en las consultas de lista de contenido. Evite indexar campos que no se usan para ordenar o filtrar porque cada índice añade sobrecarga de almacenamiento y escritura.

searchable añade el texto del campo al índice de búsqueda de texto completo de la colección. Establezca translatable: false para identificadores, precios, flags y otros valores que deben permanecer iguales en todas las traducciones de una entrada; cuando un locale cambia un campo no traducible, EmDash sincroniza el valor con sus entradas traducidas.

El tipo blocks usa solo slug, label, type, translatable, validation y sortOrder de este conjunto común. Su array nunca es obligatorio a nivel de columna y siempre tiene como valor predeterminado [].

Slugs de campo reservados

Estos slugs están reservados y no pueden usarse:

  • id
  • slug
  • status
  • author_id
  • primary_byline_id
  • created_at
  • updated_at
  • published_at
  • scheduled_at
  • deleted_at
  • version
  • live_revision_id
  • draft_revision_id
  • terms
  • bylines
  • byline

Tipos TypeScript

Importe las definiciones de tipos de campo para uso programático:

import type { FieldType, Field, CreateFieldInput } from "emdash";

const fieldTypes: FieldType[] = [
	"string",
	"text",
	"url",
	"number",
	"integer",
	"boolean",
	"datetime",
	"select",
	"multiSelect",
	"portableText",
	"image",
	"file",
	"reference",
	"json",
	"slug",
	"repeater",
	"blocks",
];