Il tipo di campo json di EmDash memorizza dati strutturati arbitrari, ma l’editor predefinito è un input di testo a riga singola dove devi digitare JSON grezzo a mano. Field Kit è un plugin di prima parte che fornisce quattro widget componibili per campi json, configurati interamente tramite options di seed — nessun React richiesto per i costruttori di siti.
Installazione
npm i @emdash-cms/plugin-field-kit
Registra il 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()],
}),
],
});
Quindi allega un widget a qualsiasi campo json impostando widget su field-kit:<name>:
{
"slug": "ingredients",
"type": "json",
"widget": "field-kit:list",
"options": { "fields": [...] }
}
Widget
| Widget | Usare per | Valore memorizzato |
|---|---|---|
object-form | Form in linea per oggetti JSON piatti | { key: value, ... } |
list | Editor di array ordinato con aggiungi / rimuovi / riordina | [{ ... }, ...] |
grid | Matrice righe × colonne | { rowKey: { colKey: value } } |
tags | Input chip/tag in forma libera | ["tag1", "tag2"] |
Se un widget manca delle sue options richieste (ad esempio fields per object-form/list, o rows/columns per grid), l’editor visualizza un avviso in linea “Widget mal configurato” invece di un input rotto — utile durante l’iterazione sugli schemi di seed.
object-form
Visualizza un gruppo di sottocampi tipizzati che vengono memorizzati come un singolo oggetto JSON. Buono per dati strutturati a forma fissa come valori nutrizionali o informazioni di contatto.
{
"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" }
]
}
}
Valore memorizzato: { "calories": 250, "protein": 12.5, "fat": 8, "carbs": 30 }.
| Opzione | Tipo | Predefinito | Descrizione |
|---|---|---|---|
fields | SubFieldDef[] | (richiesto) | Definizioni di sottocampi — vedi Sottocampi. |
collapsed | boolean | false | Visualizza il gruppo compresso per impostazione predefinita. |
helpText | string | — | Testo di aiuto mostrato sotto il widget. |
list
Un editor di array ordinato con controlli di aggiunta, rimozione e riordino. Ogni riga è un oggetto JSON la cui forma è definita da fields. L’intestazione della riga mostra un riepilogo visualizzato da un template in stile Mustache.
{
"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" }
]
}
}
Valore memorizzato:
[
{ "name": "Flour", "amount": "500g", "optional": false },
{ "name": "Butter", "amount": "200g", "optional": false }
]
| Opzione | Tipo | Predefinito | Descrizione |
|---|---|---|---|
fields | SubFieldDef[] | (richiesto) | Definizioni di sottocampi per ogni riga. |
itemLabel | string | "Item" | Etichetta singolare per una riga (usata nel pulsante “Aggiungi” e nei titoli di riga di fallback). |
min | number | — | Numero minimo di elementi. Al di sotto di questo, il pulsante di rimozione si nasconde. |
max | number | — | Numero massimo di elementi. A questo conteggio, il pulsante di aggiunta si nasconde. |
sortable | boolean | true | Mostra i pulsanti di riordino su/giù. |
summary | string | — | Template Mustache visualizzato come titolo di riga compressa. Vedi Template di riepilogo. |
helpText | string | — | Testo di aiuto mostrato sotto il widget. |
grid
Una matrice bidimensionale di righe × colonne. Ogni cella può essere un interruttore, un input di testo, un input numerico o una selezione. Utile per matrici come disponibilità stagionale, tabelle di prezzi o confronti di funzionalità.
{
"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" }
]
}
}
Valore memorizzato:
{
"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 }
}
| Opzione | Tipo | Predefinito | Descrizione |
|---|---|---|---|
rows | GridAxisDef[] | (richiesto) | Definizioni di riga: { key, label, image? }. |
columns | GridAxisDef[] | (richiesto) | Definizioni di colonna: { key, label, image? }. |
cell | "toggle" | "text" | "number" | "select" | "toggle" | Tipo di input di cella, applicato uniformemente a ogni cella. |
cellOptions | string[] | Array<{ label, value }> | [] | Richiesto quando cell è "select". |
helpText | string | — | Testo di aiuto mostrato sotto il widget. |
tags
Un input in stile chip per array di stringhe. Supporta un elenco fisso di suggestions, valori personalizzati in forma libera (commutabili), trasformazioni di maiuscole/minuscole e un max opzionale.
{
"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"]
}
}
Valore memorizzato: ["vegan", "gluten-free"].
Premi Enter o , per confermare un tag. Backspace su un input vuoto rimuove l’ultimo tag. I tag duplicati vengono silenziosamente ignorati.
| Opzione | Tipo | Predefinito | Descrizione |
|---|---|---|---|
placeholder | string | "Add..." | Segnaposto di input mostrato quando non sono presenti tag. |
max | number | — | Numero massimo di tag. L’input si nasconde al limite. |
suggestions | string[] | [] | Suggerimenti di autocompletamento visualizzati tramite una <datalist>. |
allowCustom | boolean | true | Quando false, possono essere aggiunti solo valori da suggestions. |
transform | "none" | "lowercase" | "uppercase" | "trim" | "none" | Normalizza i tag man mano che vengono aggiunti. |
helpText | string | — | Testo di aiuto mostrato sotto il widget. |
Sottocampi
object-form e list accettano un array options.fields di definizioni di sottocampi tipizzati. Ogni voce ha una key (la chiave dell’oggetto JSON in cui scrive), un label, un type e extra specifici del tipo.
| Tipo di sottocampo | Visualizzato come | Extra notevoli |
|---|---|---|
text | Input a riga singola | placeholder |
textarea | Input multiriga | rows (predefinito 3), placeholder |
number | Input numerico | min, max, step, prefix, suffix, placeholder |
boolean | Interruttore | — |
select | Menu a discesa | options: string[] | Array<{ label, value }>, placeholder |
date | Input di data | — |
color | Selettore di colore nativo abbinato a un input di testo esadecimale | — |
url | Input URL (HTML5 type="url") | placeholder |
Proprietà comuni su ogni sottocampo: required, helpText, defaultValue.
Template di riepilogo
Il widget list visualizza ogni riga compressa usando un template in stile Mustache in options.summary. {{key}} viene sostituito con il valore della riga per quella chiave (convertito in stringa). I valori falsy tornano a "{itemLabel} {n}".
"summary": "{{name}} — {{amount}}"
Visualizza righe come Flour — 500g. Il template è una semplice sostituzione di stringhe — niente HTML, niente espressioni annidate.
Durabilità dei dati
I widget di Field Kit memorizzano JSON semplice nella colonna esistente del campo. Non ci sono tabelle specifiche del plugin, nessuna chiave esterna, nessuna mutazione di schema. Se rimuovi @emdash-cms/plugin-field-kit dalla tua configurazione, i dati rimangono validi — solo l’interfaccia di modifica torna all’input di testo json predefinito.
Questo si applica anche quando cambi la forma del widget: le chiavi sconosciute sugli oggetti memorizzati vengono preservate alla prossima scrittura, quindi puoi evolvere uno schema senza perdere dati catturati sotto un set di campi più vecchio.
Vedi anche
- Panoramica dei plugin — come funzionano i plugin EmDash.
- Scelta di un formato di plugin — scrivi i tuoi widget di campo se Field Kit non si adatta.
- Discussion #571 — la proposta che ha portato a questo plugin.