EmDash supporta 17 tipi di campo per definire gli schemi di contenuto. Ogni tipo corrisponde a un tipo di colonna SQLite e fornisce l’UI di amministrazione appropriata.
Panoramica
La tabella seguente elenca ogni tipo di campo e la relativa colonna SQLite:
| Type | SQLite Column | Description |
|---|---|---|
string | TEXT | Input di testo breve |
text | TEXT | Testo multilinea |
url | TEXT | Valore URL |
number | REAL | Numero decimale |
integer | INTEGER | Numero intero |
boolean | INTEGER | Vero/falso |
datetime | TEXT | Data e ora |
select | TEXT | Scelta singola tra opzioni |
multiSelect | JSON | Scelte multiple |
portableText | JSON | Contenuto rich text |
image | TEXT | Riferimento immagine |
file | TEXT | Riferimento file |
reference | none | Collega voci di un’altra collection |
json | JSON | Dati JSON arbitrari |
slug | TEXT | Identificatore sicuro per URL |
repeater | JSON | Gruppo di campi ripetibile |
blocks | JSON | Composizione di pagina tipizzata |
Tipi di testo
string
Testo breve su una riga. Usalo per titoli, nomi e valori brevi.
{
slug: "title",
label: "Title",
type: "string",
required: true,
validation: {
minLength: 1,
maxLength: 200,
},
}
Opzioni di validazione:
minLength— Numero minimo di caratterimaxLength— Numero massimo di caratteripattern— Espressione regolare a cui il valore deve corrispondere
L’editor limita l’input a maxLength e mostra un contatore di caratteri in tempo reale rispetto alle regole di lunghezza.
Opzioni del widget:
- Nessuna specifica
text
Testo semplice multilinea. Usalo per descrizioni, estratti e testo semplice più lungo.
{
slug: "excerpt",
label: "Excerpt",
type: "text",
options: {
rows: 3,
},
}
Opzioni di validazione:
minLength— Numero minimo di caratterimaxLength— Numero massimo di caratteripattern— Espressione regolare a cui il valore deve corrispondere
L’editor limita l’input a maxLength e mostra un contatore di caratteri in tempo reale rispetto alle regole di lunghezza.
Opzioni del widget:
rows— Numero di righe nel textarea (predefinito: 3)
url
Un indirizzo web. L’API dei contenuti rifiuta i valori che non sono URL validi.
{
slug: "website",
label: "Website",
type: "url",
required: true,
}
I campi URL sono memorizzati come testo. Usa invece un campo string quando un valore può essere un percorso relativo come /about, perché i percorsi relativi non sono valori validi per un campo url.
slug
Testo destinato a contenere un valore simile a uno slug. Questo tipo di campo personalizzato non genera né sanitizza il proprio valore.
{
slug: "legacy_slug",
label: "Legacy Slug",
type: "slug",
required: true,
unique: true,
}
Ogni voce di contenuto ha già uno slug di sistema riservato, che EmDash gestisce separatamente per gli URL pubblici. Usa un campo slug personalizzato solo quando il modello di contenuto necessita di un altro valore simile a uno slug memorizzato.
Tipi numerici
number
Numero decimale. Usalo per prezzi, valutazioni e misure.
{
slug: "price",
label: "Price",
type: "number",
required: true,
validation: {
min: 0,
max: 999999.99,
},
}
Opzioni di validazione:
min— Valore minimomax— Valore massimo
L’editor imposta min e max sull’input numerico e mostra l’intervallo consentito sotto.
Memorizzato come SQLite REAL (virgola mobile a 64 bit).
integer
Numero intero. Usalo per quantità, conteggi e valori di ordine.
{
slug: "quantity",
label: "Quantity",
type: "integer",
defaultValue: 1,
validation: {
min: 0,
max: 1000,
},
}
Opzioni di validazione:
min— Valore minimomax— Valore massimo
L’editor imposta min e max sull’input numerico e mostra l’intervallo consentito sotto.
Memorizzato come SQLite INTEGER.
boolean
Vero o falso. Usalo per interruttori e flag.
{
slug: "featured",
label: "Featured",
type: "boolean",
defaultValue: false,
}
Memorizzato come SQLite INTEGER (0 o 1).
Data e ora
datetime
Un istante nel tempo. Le scritture API, MCP e CLI devono includere Z o un offset UTC esplicito. L’admin interpreta il selettore data-ora nel fuso orario configurato in Settings → General.
{
slug: "publishedAt",
label: "Published At",
type: "datetime",
}
Formato di archiviazione: 2025-01-24T12:00:00.000Z
EmDash converte l’input accettato in UTC con millisecondi a tre cifre prima di archiviarlo. Ad esempio, 2025-01-24T21:00:00+09:00 viene memorizzato come 2025-01-24T12:00:00.000Z. Usa invece un campo string quando il valore è una data di calendario o un’ora locale di orologio a muro piuttosto che un istante.
Tipi di selezione
select
Selezione singola tra opzioni predefinite.
{
slug: "status",
label: "Status",
type: "select",
required: true,
defaultValue: "draft",
validation: {
options: ["draft", "published", "archived"],
},
}
Opzioni di validazione:
options— Array opzionale di valori consentiti. Forniscilo per presentare scelte predefinite e rifiutare altre stringhe; senza di esso, la validazione accetta qualsiasi stringa.
Memorizzato come TEXT contenente il valore selezionato.
multiSelect
Selezioni multiple tra opzioni predefinite.
{
slug: "tags",
label: "Tags",
type: "multiSelect",
validation: {
options: ["news", "tutorial", "review", "opinion"],
},
}
Opzioni di validazione:
options— Array opzionale di valori consentiti. Forniscilo per presentare scelte predefinite e rifiutare altre stringhe; senza di esso, la validazione accetta qualsiasi array di stringhe.
Memorizzato come array JSON: ["news", "tutorial"]
Contenuto ricco
portableText
Contenuto rich text in formato Portable Text. Supporta intestazioni, elenchi, link, immagini e blocchi personalizzati.
{
slug: "content",
label: "Content",
type: "portableText",
required: true,
}
Il valore è memorizzato come un array JSON di blocchi Portable Text, ad esempio:
[
{
"_type": "block",
"style": "normal",
"children": [{ "_type": "span", "text": "Hello world" }]
}
]
I plugin possono aggiungere tipi di blocco personalizzati (embed, widget, ecc.) all’editor. Compaiono nel menu dei comandi slash. Il rendering del blocco salvato sul sito pubblico richiede un componente Astro da un plugin nativo o un pacchetto companion. Vedi Componenti di rendering Portable Text.
Tipi media
image
Riferimento a un’immagine caricata. Include metadati come dimensioni e testo alternativo.
{
slug: "featuredImage",
label: "Featured Image",
type: "image",
validation: {
allowedMimeTypes: ["image/jpeg", "image/png"],
},
options: {
darkVariant: true,
},
}
Opzioni del widget:
darkVariant— Offre agli editor un secondo slot per un’immagine mostrata negli schemi di colore scuri (predefinito: false). Vedi Dark Mode.
Opzioni di validazione:
allowedMimeTypes— Elenco non vuoto di tipi MIME esatti accettati per il media selezionato
Il valore è memorizzato come un oggetto con il riferimento media e i suoi metadati:
{
"id": "01HXK5MZSN...",
"src": "/_emdash/api/media/file/01HXK5MZSN...",
"alt": "Description",
"width": 1920,
"height": 1080,
"provider": "local",
"meta": {
"storageKey": "01HXK5MZSN....jpg"
}
}
Con darkVariant abilitato, il valore può portare la controparte scura sotto darkVariant, nella stessa forma:
{
"id": "01HXK5MZSN...",
"alt": "Architecture diagram",
"width": 1920,
"height": 1080,
"darkVariant": {
"id": "01HXK5N2QT...",
"width": 1920,
"height": 1080
}
}
file
Riferimento a un file caricato come un documento o PDF.
{
slug: "document",
label: "Document",
type: "file",
validation: {
allowedMimeTypes: ["application/pdf"],
},
}
Opzioni di validazione:
allowedMimeTypes— Elenco non vuoto di tipi MIME esatti accettati per il media selezionato
Il valore è memorizzato come un riferimento al provider con metadati in cache:
{
"id": "01HXK5MZSN...",
"provider": "local",
"filename": "report.pdf",
"mimeType": "application/pdf",
"meta": {
"storageKey": "01HXK5MZSN....pdf"
}
}
url e size, come gli altri campi di metadati in cache, sono opzionali. Le query sui contenuti restituiscono il
valore persistito così com’è e non lo idratano dalla libreria media. Vedi
Valori file e metadati correnti per le
API di lookup canoniche quando ti servono metadati aggiornati o un URL specifico del provider.
Tipi relazionali
reference
Collega una voce a voci di un’altra collection e viene visualizzato come selettore di voci nell’admin. I suoi collegamenti appartengono a una relazione: un oggetto schema che unisce due collection, nomina ciascun lato e limita quante voci ciascun lato può collegare. Relations copre il flusso di lavoro editor e admin.
Il campo seguente collega un post a una voce della collection authors:
{
slug: "author",
label: "Author",
type: "reference",
required: true,
validation: {
targetCollection: "authors",
multiple: false,
},
}
Validazione:
targetCollection— Slug della collection a cui questo campo si collega. Creare il campo crea una relazione per esso.multiple— Consentire più di una voce collegata (predefinito: false). Leggilo solo insieme atargetCollection, perché il limite appartiene allora alla nuova relazione.relation— Slug di una relazione esistente a cui associarsi invece di crearne una.relationSide— Su quale estremità direlationsi trova questa collection,"parent"o"child". Impostalo solo per una relazione le cui due estremità sono la stessa collection, dove entrambe le estremità corrispondono.
Indica targetCollection oppure relation. Un campo creato da targetCollection diventa l’
estremità padre di una relazione chiamata {collection}_{field}, il cui lato figlio prende l’etichetta del campo e
contiene una voce a meno che non sia impostato multiple. Un campo creato da relation vede quella relazione dall’
estremità su cui si trova la sua collection, e la collection all’altra estremità è la destinazione del campo. Una
relazione accetta un campo per estremità, quindi un secondo campo sulla stessa estremità viene rifiutato. Entrambe le forme
memorizzano relation, relationSide e targetCollection sul campo creato, e la collection
destinazione è fissa da allora: per cambiarla, elimina il campo e aggiungine uno nuovo. Rinominare il
campo rinomina il lato della relazione che vede.
Un campo reference non aggiunge alcuna colonna alla tabella della collection. I suoi collegamenti vivono in
_emdash_content_references, indicizzati dal gruppo di traduzione di ciascuna voce, così una selezione è condivisa
tra le traduzioni di una voce anziché impostata per locale. Le letture di contenuto restituiscono le voci collegate
sotto references, indicizzate dallo slug del campo, invece che in data. In un template, richiedi il campo per
nome — vedi Leggere i campi reference.
Un campo associato a una relazione non può impostare indexed, perché non memorizza alcuna colonna da indicizzare, e la ricerca
del sito non lo copre.
Campi senza relazione
Un campo reference che non nomina né una relazione né una collection destinazione conserva una colonna TEXT e
vi contiene un ID voce:
"01HXK5MZSN..."
Un campo il cui options.allowMultiple è impostato contiene un array JSON di ID voce nella stessa colonna:
["01HXK5MZSN...", "01HXK6NATS..."]
La colonna viene letta e scritta come qualsiasi altra colonna di testo, lo schema della collection valida il
valore come stringa, e il campo può impostare indexed e fungere da filtro dell’elenco contenuti. Viene visualizzato come una
casella di testo anziché un selettore.
Per trasformarlo in un selettore, apri il campo in Content Types e scegli una collection referenziata.
EmDash crea la relazione, copia gli ID voce nella colonna come collegamenti e cancella i flag
searchable e indexed del campo, così i filtri dell’elenco contenuti e la ricerca del sito smettono di coprirlo. La
colonna resta al suo posto e non viene più scritta. Relations
copre lo stesso passaggio dal lato dell’editor.
Un sito aggiornato da una versione precedente può mantenere campi in questo stato. Vedi I campi reference si associano alle relazioni per ciò che l’aggiornamento associa e ciò che lascia a te da associare.
Tipi flessibili
json
Dati JSON arbitrari. Usali per strutture annidate complesse, integrazioni di terze parti o dati senza uno schema fisso.
{
slug: "metadata",
label: "Metadata",
type: "json",
}
Memorizzato così com’è in una colonna JSON SQLite.
repeater
Un elenco ripetibile di righe strutturate. Definisci almeno un sotto-campo in validation.subFields; gli editor possono quindi aggiungere, rimuovere, riordinare e modificare le righe senza inserire JSON grezzo.
Il campo seguente memorizza un elenco di specifiche prodotto:
{
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" },
],
},
}
I valori repeater sono memorizzati come un array di oggetti:
[
{
"label": "Weight",
"value": "1.2 kg",
"source": "https://example.com/specifications"
}
]
I tipi di sotto-campo consentiti sono string, text, url, number, integer, boolean, datetime, select e image. I repeater non possono contenere un altro repeater né un campo complesso come portableText, reference o file.
La validazione repeater accetta queste proprietà:
subFields— Una o più definizioni di sotto-campo. Ogni definizione richiedeslug,labeletype; può anche impostarerequired. Un sotto-camposelectfornisce le sue scelte tramiteoptions.minItems— Numero minimo di righe. Deve essere zero o maggiore.maxItems— Numero massimo di righe. Deve essere uno o maggiore e non può essere inferiore aminItems.
blocks
Un elenco ordinato di blocchi di contenuto tipizzati. Ogni tipo di blocco ha i propri campi e conserva versioni numerate. Definisci i tipi di blocco tramite l’API dello schema, MCP o un file seed prima di aggiungerli a un campo della collection.
Il campo seguente consente agli editor di comporre una pagina da blocchi hero e call-to-action:
{
slug: "layout",
label: "Layout",
type: "blocks",
validation: {
allowedTypes: ["hero", "call_to_action"],
maxItems: 20,
},
}
Ogni blocco memorizzato porta tipo, versione e chiave stabile insieme ai campi dichiarati da quella versione:
[
{
"_type": "hero",
"_version": 1,
"_key": "01K5AB3F7M9QZ2X8W4V6T1R0YH",
"heading": "Bread made slowly, by hand."
}
]
La validazione blocks accetta queste proprietà:
allowedTypes— Slug dei tipi di blocco ordinati disponibili per nuovi blocchi.retiredTypes— Tipi di blocco gestiti dal server trattenuti per il contenuto memorizzato ma non disponibili per nuovi blocchi.minItems— Numero minimo di blocchi. Aumentarlo oltre zero su una collection popolata richiede una migrazione dei contenuti.maxItems— Numero massimo di blocchi, fino a 100.
Un campo blocks è opzionale e per impostazione predefinita è un array vuoto. Non può essere required, unique, searchable, indexed, né reso da un widget di campo personalizzato. Le definizioni di blocco possono usare campi scalari, testo, selezione, Portable Text, immagine, file e repeater. Non possono contenere riferimenti, JSON, slug o blocks annidati.
Esegui il rendering dell’array memorizzato con <Blocks value components fallback> da emdash/ui. Vedi Creare pagine con i blocks per esempi di seed, mappa dei componenti, renderer mancante, attivazione e migrazione.
Proprietà dei campi
Tutti i campi supportano queste proprietà comuni:
| Property | Type | Description |
|---|---|---|
slug | string | Identificatore univoco (obbligatorio) |
label | string | Nome visualizzato (obbligatorio) |
type | FieldType | Tipo di campo (obbligatorio) |
required | boolean | Richiedere un valore (predefinito: false) |
unique | boolean | Imporre l’unicità (predefinito: false) |
searchable | boolean | Includere il campo nella ricerca full-text (predefinito: false) |
indexed | boolean | Abilitare ordinamento/filtro indicizzato |
translatable | boolean | Memorizzare un valore per locale (predefinito: true) |
defaultValue | unknown | Valore predefinito per nuove voci |
validation | object | Regole di validazione specifiche del tipo |
widget | string | Override del widget personalizzato |
options | object | Configurazione del widget |
sortOrder | number | Ordine di visualizzazione nell’admin |
indexed è disponibile per i campi scalari: string, url, number, integer, boolean,
datetime, select, reference e slug. Un campo indicizzato può essere passato come campo orderBy
o usato in fieldFilters nelle query dell’elenco contenuti. Evita di indicizzare campi che non vengono usati
per ordinare o filtrare perché ogni indice aggiunge overhead di archiviazione e scrittura.
searchable aggiunge il testo del campo all’indice di ricerca full-text della collection. Imposta translatable: false per identificatori, prezzi, flag e altri valori che devono restare uguali in ogni traduzione di una voce; quando un locale modifica un campo non traducibile, EmDash sincronizza il valore alle sue voci tradotte.
Il tipo blocks usa solo slug, label, type, translatable, validation e sortOrder da questo insieme comune. Il suo array non è mai obbligatorio a livello di colonna e ha sempre come valore predefinito [].
Slug di campo riservati
Questi slug sono riservati e non possono essere usati:
idslugstatusauthor_idprimary_byline_idcreated_atupdated_atpublished_atscheduled_atdeleted_atversionlive_revision_iddraft_revision_idtermsbylinesbyline
Tipi TypeScript
Importa le definizioni dei tipi di campo per uso programmatico:
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",
];