Field Kit

En esta página

El tipo de campo json de EmDash almacena datos estructurados arbitrarios, editados de forma predeterminada a través de una entrada de texto de una sola línea que acepta JSON sin procesar. Field Kit es un plugin oficial que incluye cuatro widgets componibles para campos json, configurados completamente mediante options de seed para que los constructores de sitios puedan usarlos solo con el esquema de seed.

Instalación

Instala el paquete desde npm:

npm i @emdash-cms/plugin-field-kit

La siguiente configuración registra el plugin:

import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { fieldKitPlugin } from "@emdash-cms/plugin-field-kit";

export default defineConfig({
	integrations: [
		emdash({
			plugins: [fieldKitPlugin()],
		}),
	],
});

Adjunta un widget a cualquier campo json estableciendo widget en field-kit:<name>. La siguiente definición de campo usa el widget list:

{
	"slug": "ingredients",
	"type": "json",
	"widget": "field-kit:list",
	"options": { "fields": [...] }
}

Widgets

WidgetUsoValor almacenado
object-formFormulario en línea para objetos JSON planos{ key: value, ... }
listEditor de array ordenado con agregar / eliminar / reordenar[{ ... }, ...]
gridMatriz de filas × columnas{ rowKey: { colKey: value } }
tagsEntrada de chip/etiqueta de forma libre["tag1", "tag2"]

Si a un widget le faltan sus options requeridas (por ejemplo, fields para object-form/list, o rows/columns para grid), el editor muestra una advertencia en línea “Widget mal configurado” en lugar de una entrada rota — útil mientras se itera en esquemas de seed.

object-form

Renderiza un grupo de subcampos tipados que se almacenan como un único objeto JSON. Bueno para datos estructurados de forma fija como información nutricional o de contacto. La siguiente definición de campo configura un objeto de nutrición:

{
	"slug": "nutrition",
	"type": "json",
	"widget": "field-kit:object-form",
	"options": {
		"collapsed": false,
		"fields": [
			{ "key": "calories", "label": "Calories", "type": "number", "suffix": "kcal" },
			{ "key": "protein", "label": "Protein", "type": "number", "suffix": "g" },
			{ "key": "fat", "label": "Fat", "type": "number", "suffix": "g" },
			{ "key": "carbs", "label": "Carbs", "type": "number", "suffix": "g" }
		]
	}
}

Valor almacenado: { "calories": 250, "protein": 12.5, "fat": 8, "carbs": 30 }.

OpciónTipoPredeterminadoDescripción
fieldsSubFieldDef[](requerido)Definiciones de subcampos — ver Subcampos.
collapsedbooleanfalseRenderizar el grupo contraído por defecto.
helpTextstringTexto de ayuda mostrado debajo del widget.

list

Un editor de array ordenado con controles de agregar, eliminar y reordenar. Cada fila es un objeto JSON cuya forma está definida por fields. El encabezado de fila muestra un resumen renderizado desde una plantilla estilo Mustache. La siguiente definición de campo configura una lista de ingredientes:

{
	"slug": "ingredients",
	"type": "json",
	"widget": "field-kit:list",
	"options": {
		"itemLabel": "Ingredient",
		"min": 1,
		"max": 50,
		"sortable": true,
		"summary": "{{name}} — {{amount}}",
		"fields": [
			{ "key": "name", "label": "Name", "type": "text", "required": true },
			{ "key": "amount", "label": "Amount", "type": "text" },
			{ "key": "optional", "label": "Optional", "type": "boolean" }
		]
	}
}

El valor almacenado es un array de objetos de fila:

[
	{ "name": "Flour", "amount": "500g", "optional": false },
	{ "name": "Butter", "amount": "200g", "optional": false }
]
OpciónTipoPredeterminadoDescripción
fieldsSubFieldDef[](requerido)Definiciones de subcampos para cada fila.
itemLabelstring"Item"Etiqueta singular para una fila (usada en el botón “Agregar” y títulos de fila de respaldo).
minnumberNúmero mínimo de elementos. Por debajo de esto, el botón eliminar se oculta.
maxnumberNúmero máximo de elementos. En este recuento, el botón agregar se oculta.
sortablebooleantrueMostrar botones de reordenar arriba/abajo.
summarystringPlantilla Mustache renderizada como el título de fila contraída. Ver Plantillas de resumen.
helpTextstringTexto de ayuda mostrado debajo del widget.

grid

Una matriz bidimensional de filas × columnas. Cada celda puede ser un interruptor, entrada de texto, entrada numérica o selección. Útil para matrices como disponibilidad estacional, tablas de precios o comparaciones de características. La siguiente definición de campo configura una cuadrícula de disponibilidad estacional:

{
	"slug": "availability",
	"type": "json",
	"widget": "field-kit:grid",
	"options": {
		"cell": "toggle",
		"rows": [
			{ "key": "berries", "label": "Berries" },
			{ "key": "stoneFruit", "label": "Stone fruit" },
			{ "key": "citrus", "label": "Citrus" }
		],
		"columns": [
			{ "key": "spring", "label": "Spring" },
			{ "key": "summer", "label": "Summer" },
			{ "key": "autumn", "label": "Autumn" },
			{ "key": "winter", "label": "Winter" }
		]
	}
}

El valor almacenado es un objeto indexado por fila, luego por columna:

{
	"berries": { "spring": false, "summer": true, "autumn": false, "winter": false },
	"stoneFruit": { "spring": false, "summer": true, "autumn": true, "winter": false },
	"citrus": { "spring": false, "summer": false, "autumn": true, "winter": true }
}
OpciónTipoPredeterminadoDescripción
rowsGridAxisDef[](requerido)Definiciones de filas: { key, label, image? }.
columnsGridAxisDef[](requerido)Definiciones de columnas: { key, label, image? }.
cell"toggle" | "text" | "number" | "select""toggle"Tipo de entrada de celda, aplicado uniformemente a cada celda.
cellOptionsstring[] | Array<{ label, value }>[]Requerido cuando cell es "select".
helpTextstringTexto de ayuda mostrado debajo del widget.

tags

Una entrada estilo chip para arrays de cadenas. Admite una lista fija de suggestions, valores personalizados de forma libre (conmutable), transformaciones de mayúsculas/minúsculas y un max opcional. La siguiente definición de campo configura una entrada de etiquetas de palabras clave:

{
	"slug": "keywords",
	"type": "json",
	"widget": "field-kit:tags",
	"options": {
		"placeholder": "Add a keyword…",
		"max": 10,
		"transform": "lowercase",
		"allowCustom": true,
		"suggestions": ["vegan", "vegetarian", "gluten-free", "dairy-free", "nut-free"]
	}
}

Valor almacenado: ["vegan", "gluten-free"].

Presiona Enter o , para confirmar una etiqueta. Backspace en una entrada vacía elimina la última etiqueta. Las etiquetas duplicadas se ignoran silenciosamente.

OpciónTipoPredeterminadoDescripción
placeholderstring"Add..."Marcador de posición de entrada mostrado cuando no hay etiquetas presentes.
maxnumberNúmero máximo de etiquetas. La entrada se oculta en el límite.
suggestionsstring[][]Sugerencias de autocompletado mostradas a través de un <datalist>.
allowCustombooleantrueCuando es false, solo se pueden agregar valores de suggestions.
transform"none" | "lowercase" | "uppercase" | "trim""none"Normalizar etiquetas a medida que se agregan.
helpTextstringTexto de ayuda mostrado debajo del widget.

Subcampos

object-form y list aceptan un array options.fields de definiciones de subcampos tipados. Cada entrada tiene un key (la clave del objeto JSON en la que escribe), un label, un type y extras específicos del tipo.

Tipo de subcampoSe renderiza comoExtras notables
textEntrada de una líneaplaceholder
textareaEntrada multilínearows (predeterminado 3), placeholder
numberEntrada numéricamin, max, step, prefix, suffix, placeholder
booleanInterruptor de alternancia
selectDesplegableoptions: string[] | Array<{ label, value }>, placeholder
dateEntrada de fecha
colorSelector de color nativo emparejado con una entrada de texto hexadecimal
urlEntrada URL (HTML5 type="url")placeholder

Propiedades comunes en cada subcampo: required, helpText, defaultValue.

Plantillas de resumen

El widget list renderiza cada fila contraída usando una plantilla estilo Mustache en options.summary. {{key}} se reemplaza con el valor de la fila para esa clave (convertido a una cadena). Los valores falsos vuelven a "{itemLabel} {n}". La siguiente plantilla combina dos claves:

"summary": "{{name}} — {{amount}}"

Renderiza filas como Flour — 500g. La plantilla es sustitución de cadena simple — sin HTML, sin expresiones anidadas.

Durabilidad de datos

Los widgets de Field Kit almacenan JSON simple en la columna existente del campo, usando solo esa columna. Si eliminas @emdash-cms/plugin-field-kit de tu configuración, los datos permanecen válidos — el campo vuelve a la entrada de texto json predeterminada.

Esto se aplica incluso cuando cambias la forma del widget: las claves desconocidas en objetos almacenados se preservan en la siguiente escritura, por lo que puedes evolucionar un esquema sin perder datos capturados bajo un conjunto de campos más antiguo.

Ver también