EmDashs json-Feldtyp speichert beliebige strukturierte Daten, aber der Standard-Editor ist ein einzeiliges Texteingabefeld, in dem Sie rohes JSON von Hand eingeben müssen. Field Kit ist ein First-Party-Plugin, das vier zusammensetzbare Widgets für json-Felder liefert, die vollständig über Seed-options konfiguriert werden — ohne React-Kenntnisse für Website-Ersteller.
Installation
npm i @emdash-cms/plugin-field-kit
Registrieren Sie das Plugin in astro.config.mjs:
import { defineConfig } from "astro/config";
import emdash from "emdash";
import { fieldKitPlugin } from "@emdash-cms/plugin-field-kit";
export default defineConfig({
integrations: [
emdash({
plugins: [fieldKitPlugin()],
}),
],
});
Fügen Sie dann ein Widget zu einem beliebigen json-Feld hinzu, indem Sie widget auf field-kit:<name> setzen:
{
"slug": "ingredients",
"type": "json",
"widget": "field-kit:list",
"options": { "fields": [...] }
}
Widgets
| Widget | Verwendung | Gespeicherter Wert |
|---|---|---|
object-form | Inline-Formular für flache JSON-Objekte | { key: value, ... } |
list | Geordneter Array-Editor mit Hinzufügen / Entfernen / Neuordnen | [{ ... }, ...] |
grid | Zeilen × Spalten-Matrix | { rowKey: { colKey: value } } |
tags | Freiform-Chip/Tag-Eingabe | ["tag1", "tag2"] |
Wenn einem Widget die erforderlichen options fehlen (z. B. fields für object-form/list oder rows/columns für grid), rendert der Editor eine Inline-Warnung “Widget falsch konfiguriert” anstelle einer defekten Eingabe — nützlich beim Iterieren von Seed-Schemas.
object-form
Rendert eine Gruppe typisierter Unterfelder, die als einzelnes JSON-Objekt gespeichert werden. Gut für strukturierte Daten mit fester Form wie Nährwertangaben oder Kontaktinformationen.
{
"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" }
]
}
}
Gespeicherter Wert: { "calories": 250, "protein": 12.5, "fat": 8, "carbs": 30 }.
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
fields | SubFieldDef[] | (erforderlich) | Unterfeld-Definitionen — siehe Unterfelder. |
collapsed | boolean | false | Gruppe standardmäßig eingeklappt rendern. |
helpText | string | — | Hilfstext unterhalb des Widgets angezeigt. |
list
Ein geordneter Array-Editor mit Hinzufügen-, Entfernen- und Neuordnen-Steuerungen. Jede Zeile ist ein JSON-Objekt, dessen Form durch fields definiert ist. Der Zeilenkopf zeigt eine Zusammenfassung, die aus einer Mustache-Vorlage gerendert wird.
{
"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" }
]
}
}
Gespeicherter Wert:
[
{ "name": "Flour", "amount": "500g", "optional": false },
{ "name": "Butter", "amount": "200g", "optional": false }
]
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
fields | SubFieldDef[] | (erforderlich) | Unterfeld-Definitionen für jede Zeile. |
itemLabel | string | "Item" | Singularform für eine Zeile (verwendet in der “Hinzufügen”-Schaltfläche und Fallback-Zeilentiteln). |
min | number | — | Mindestanzahl von Elementen. Darunter wird die Entfernen-Schaltfläche ausgeblendet. |
max | number | — | Maximale Anzahl von Elementen. Bei dieser Anzahl wird die Hinzufügen-Schaltfläche ausgeblendet. |
sortable | boolean | true | Aufwärts-/Abwärts-Neuordnungsschaltflächen anzeigen. |
summary | string | — | Mustache-Vorlage als eingeklappter Zeilentitel gerendert. Siehe Zusammenfassungsvorlagen. |
helpText | string | — | Hilfstext unterhalb des Widgets angezeigt. |
grid
Eine zweidimensionale Matrix aus Zeilen × Spalten. Jede Zelle kann ein Umschalter, eine Texteingabe, eine Zahleneingabe oder eine Auswahl sein. Nützlich für Matrizen wie saisonale Verfügbarkeit, Preistabellen oder Funktionsvergleiche.
{
"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" }
]
}
}
Gespeicherter Wert:
{
"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 }
}
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
rows | GridAxisDef[] | (erforderlich) | Zeilendefinitionen: { key, label, image? }. |
columns | GridAxisDef[] | (erforderlich) | Spaltendefinitionen: { key, label, image? }. |
cell | "toggle" | "text" | "number" | "select" | "toggle" | Zelleneingabetyp, gleichmäßig auf jede Zelle angewendet. |
cellOptions | string[] | Array<{ label, value }> | [] | Erforderlich, wenn cell "select" ist. |
helpText | string | — | Hilfstext unterhalb des Widgets angezeigt. |
tags
Eine Chip-Eingabe für String-Arrays. Unterstützt eine feste suggestions-Liste, benutzerdefinierte Freiform-Werte (umschaltbar), Groß-/Kleinschreibungsumwandlungen und ein optionales max.
{
"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"]
}
}
Gespeicherter Wert: ["vegan", "gluten-free"].
Drücken Sie Enter oder ,, um ein Tag zu übernehmen. Backspace bei einer leeren Eingabe entfernt das letzte Tag. Doppelte Tags werden stillschweigend ignoriert.
| Option | Typ | Standard | Beschreibung |
|---|---|---|---|
placeholder | string | "Add..." | Eingabe-Platzhalter, der angezeigt wird, wenn keine Tags vorhanden sind. |
max | number | — | Maximale Anzahl von Tags. Die Eingabe wird beim Limit ausgeblendet. |
suggestions | string[] | [] | Autovervollständigungsvorschläge über eine <datalist> angezeigt. |
allowCustom | boolean | true | Wenn false, können nur Werte aus suggestions hinzugefügt werden. |
transform | "none" | "lowercase" | "uppercase" | "trim" | "none" | Tags beim Hinzufügen normalisieren. |
helpText | string | — | Hilfstext unterhalb des Widgets angezeigt. |
Unterfelder
object-form und list akzeptieren ein options.fields-Array von typisierten Unterfeld-Definitionen. Jeder Eintrag hat einen key (den JSON-Objektschlüssel, in den er schreibt), ein label, einen type und typspezifische Extras.
| Unterfeldtyp | Wird gerendert als | Bemerkenswerte Extras |
|---|---|---|
text | Einzeilige Eingabe | placeholder |
textarea | Mehrzeilige Eingabe | rows (Standard 3), placeholder |
number | Numerische Eingabe | min, max, step, prefix, suffix, placeholder |
boolean | Umschalter | — |
select | Dropdown | options: string[] | Array<{ label, value }>, placeholder |
date | Datumseingabe | — |
color | Native Farbauswahl mit Hex-Texteingabe | — |
url | URL-Eingabe (HTML5 type="url") | placeholder |
Gemeinsame Props für jedes Unterfeld: required, helpText, defaultValue.
Zusammenfassungsvorlagen
Das list-Widget rendert jede eingeklappte Zeile mithilfe einer Mustache-Vorlage in options.summary. {{key}} wird durch den Wert der Zeile für diesen Schlüssel ersetzt (zu einem String umgewandelt). Falsy-Werte fallen auf "{itemLabel} {n}" zurück.
"summary": "{{name}} — {{amount}}"
Rendert Zeilen wie Flour — 500g. Die Vorlage ist eine einfache String-Ersetzung — kein HTML, keine verschachtelten Ausdrücke.
Datenhaltbarkeit
Field Kit-Widgets speichern reines JSON in der bestehenden Spalte des Felds. Es gibt keine plugin-spezifischen Tabellen, keine Fremdschlüssel, keine Schema-Mutation. Wenn Sie @emdash-cms/plugin-field-kit aus Ihrer Konfiguration entfernen, bleiben die Daten gültig — nur die Bearbeitungs-UI wechselt zurück zur Standard-json-Texteingabe.
Dies gilt auch, wenn Sie die Widget-Form ändern: Unbekannte Schlüssel auf gespeicherten Objekten werden beim nächsten Schreibvorgang beibehalten, sodass Sie ein Schema weiterentwickeln können, ohne Daten zu verlieren, die unter einem älteren Feldset erfasst wurden.
Siehe auch
- Plugin-Übersicht — wie EmDash-Plugins funktionieren.
- Auswahl eines Plugin-Formats — schreiben Sie Ihre eigenen Feld-Widgets, wenn Field Kit nicht passt.
- Discussion #571 — der Vorschlag, der zu diesem Plugin geführt hat.