Field Kit

本页内容

EmDash 的 json 字段类型可存储任意结构化数据,但默认编辑器是单行文本输入,需要手动输入原始 JSON。Field Kit 是一个第一方插件,为 json 字段提供四个可组合的小部件,完全通过 seed options 配置 — 网站构建者无需使用 React。

安装

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

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()],
		}),
	],
});

然后通过将 widget 设置为 field-kit:<name> 来为任何 json 字段附加小部件:

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

小部件

小部件用途存储值
object-form扁平 JSON 对象的内联表单{ key: value, ... }
list带有添加/删除/重排功能的有序数组编辑器[{ ... }, ...]
grid行 × 列矩阵{ rowKey: { colKey: value } }
tags自由形式的标签/芯片输入["tag1", "tag2"]

如果小部件缺少必需的 options(例如 object-form/listfields,或 gridrows/columns),编辑器会渲染内联警告”小部件配置错误”而不是损坏的输入 — 这在迭代 seed 架构时很有用。

object-form

渲染一组类型化的子字段,作为单个 JSON 对象存储。适用于固定形状的结构化数据,如营养成分或联系信息。

{
	"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" }
		]
	}
}

存储值:{ "calories": 250, "protein": 12.5, "fat": 8, "carbs": 30 }

选项类型默认值描述
fieldsSubFieldDef[](必需)子字段定义 — 参见子字段
collapsedbooleanfalse默认折叠渲染组。
helpTextstring小部件下方显示的帮助文本。

list

带有添加、删除和重新排序控件的有序数组编辑器。每一行是一个 JSON 对象,其形状由 fields 定义。行标题显示从 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" }
		]
	}
}

存储值:

[
	{ "name": "Flour", "amount": "500g", "optional": false },
	{ "name": "Butter", "amount": "200g", "optional": false }
]
选项类型默认值描述
fieldsSubFieldDef[](必需)每行的子字段定义。
itemLabelstring"Item"行的单数标签(用于”添加”按钮和后备行标题)。
minnumber最小项目数。低于此数时,删除按钮隐藏。
maxnumber最大项目数。达到此数时,添加按钮隐藏。
sortablebooleantrue显示上/下重排按钮。
summarystring作为折叠行标题渲染的 Mustache 模板。参见摘要模板
helpTextstring小部件下方显示的帮助文本。

grid

行 × 列的二维矩阵。每个单元格可以是开关、文本输入、数字输入或选择。适用于季节性可用性、价格表或功能比较等矩阵。

{
	"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" }
		]
	}
}

存储值:

{
	"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 }
}
选项类型默认值描述
rowsGridAxisDef[](必需)行定义:{ key, label, image? }
columnsGridAxisDef[](必需)列定义:{ key, label, image? }
cell"toggle" | "text" | "number" | "select""toggle"单元格输入类型,统一应用于每个单元格。
cellOptionsstring[] | Array<{ label, value }>[]cell"select" 时必需。
helpTextstring小部件下方显示的帮助文本。

tags

用于字符串数组的芯片样式输入。支持固定的 suggestions 列表、自由形式的自定义值(可切换)、大小写转换和可选的 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"]
	}
}

存储值:["vegan", "gluten-free"]

Enter, 提交标签。在空输入上按 Backspace 删除最后一个标签。重复标签会被静默忽略。

选项类型默认值描述
placeholderstring"Add..."没有标签时显示的输入占位符。
maxnumber最大标签数。达到限制时输入隐藏。
suggestionsstring[][]通过 <datalist> 显示的自动完成建议。
allowCustombooleantrue当为 false 时,只能添加来自 suggestions 的值。
transform"none" | "lowercase" | "uppercase" | "trim""none"添加标签时进行规范化。
helpTextstring小部件下方显示的帮助文本。

子字段

object-formlist 接受类型化子字段定义的 options.fields 数组。每个条目都有一个 key(它写入的 JSON 对象键)、一个 label、一个 type 和特定于类型的额外内容。

子字段类型渲染为值得注意的额外内容
text单行输入placeholder
textarea多行输入rows(默认 3)、placeholder
number数字输入minmaxstepprefixsuffixplaceholder
boolean切换开关
select下拉菜单options: string[] | Array<{ label, value }>placeholder
date日期输入
color配对十六进制文本输入的原生颜色选择器
urlURL 输入(HTML5 type="url"placeholder

每个子字段的通用属性:requiredhelpTextdefaultValue

摘要模板

list 小部件使用 options.summary 中的 Mustache 风格模板渲染每个折叠行。{{key}} 被替换为该键的行值(强制转换为字符串)。假值回退到 "{itemLabel} {n}"

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

渲染类似 Flour — 500g 的行。模板是简单的字符串替换 — 没有 HTML,没有嵌套表达式。

数据持久性

Field Kit 小部件在字段的现有列中存储纯 JSON。没有特定于插件的表,没有外键,没有架构变更。如果您从配置中删除 @emdash-cms/plugin-field-kit,数据仍然有效 — 只有编辑 UI 会恢复到默认的 json 文本输入。

即使更改小部件形状也适用:存储对象上的未知键在下次写入时保留,因此您可以在不丢失在旧字段集下捕获的数据的情况下演变架构。

另请参阅