EmDash 支持 17 种用于定义内容模式的字段类型。每种类型对应一个 SQLite 列类型,并提供相应的管理 UI。
概览
下表列出每种字段类型及其 SQLite 列:
| Type | SQLite Column | Description |
|---|---|---|
string | TEXT | 短文本输入 |
text | TEXT | 多行文本 |
url | TEXT | URL 值 |
number | REAL | 小数 |
integer | INTEGER | 整数 |
boolean | INTEGER | 真/假 |
datetime | TEXT | 日期与时间 |
select | TEXT | 从选项中单选 |
multiSelect | JSON | 多选 |
portableText | JSON | 富文本内容 |
image | TEXT | 图片引用 |
file | TEXT | 文件引用 |
reference | none | 链接到另一集合中的条目 |
json | JSON | 任意 JSON 数据 |
slug | TEXT | URL 安全标识符 |
repeater | JSON | 可重复字段组 |
blocks | JSON | 类型化页面组合 |
文本类型
string
短单行文本。用于标题、名称和短值。
{
slug: "title",
label: "Title",
type: "string",
required: true,
validation: {
minLength: 1,
maxLength: 200,
},
}
验证选项:
minLength— 最小字符数maxLength— 最大字符数pattern— 值必须匹配的正则表达式
编辑器将输入限制为 maxLength,并对照长度规则显示实时字符计数。
小组件选项:
- 无特定选项
text
多行纯文本。用于描述、摘要和较长的纯文本。
{
slug: "excerpt",
label: "Excerpt",
type: "text",
options: {
rows: 3,
},
}
验证选项:
minLength— 最小字符数maxLength— 最大字符数pattern— 值必须匹配的正则表达式
编辑器将输入限制为 maxLength,并对照长度规则显示实时字符计数。
小组件选项:
rows— 文本区域行数(默认:3)
url
网址。内容 API 会拒绝不是有效 URL 的值。
{
slug: "website",
label: "Website",
type: "url",
required: true,
}
URL 字段以文本形式存储。当值可能是相对路径(如 /about)时,请改用 string 字段,因为相对路径不是 url 字段的有效值。
slug
用于保存类似 slug 值的文本。此自定义字段类型不会生成或清理其值。
{
slug: "legacy_slug",
label: "Legacy Slug",
type: "slug",
required: true,
unique: true,
}
每个内容条目都已有一个保留的系统 slug,由 EmDash 单独管理用于公开 URL。仅当内容模型需要另一个已存储的类似 slug 值时,才使用自定义 slug 字段。
数字类型
number
小数。用于价格、评分和度量。
{
slug: "price",
label: "Price",
type: "number",
required: true,
validation: {
min: 0,
max: 999999.99,
},
}
验证选项:
min— 最小值max— 最大值
编辑器在数字输入上设置 min 和 max,并在下方显示允许范围。
存储为 SQLite REAL(64 位浮点)。
integer
整数。用于数量、计数和顺序值。
{
slug: "quantity",
label: "Quantity",
type: "integer",
defaultValue: 1,
validation: {
min: 0,
max: 1000,
},
}
验证选项:
min— 最小值max— 最大值
编辑器在数字输入上设置 min 和 max,并在下方显示允许范围。
存储为 SQLite INTEGER。
boolean
真或假。用于开关和标志。
{
slug: "featured",
label: "Featured",
type: "boolean",
defaultValue: false,
}
存储为 SQLite INTEGER(0 或 1)。
日期与时间
datetime
时间上的一个瞬间。API、MCP 和 CLI 写入必须包含 Z 或显式 UTC 偏移。管理端在 Settings → General 配置的时区中解释其日期时间选择器。
{
slug: "publishedAt",
label: "Published At",
type: "datetime",
}
存储格式: 2025-01-24T12:00:00.000Z
EmDash 在存储前将接受的输入转换为带三位毫秒的 UTC。例如,2025-01-24T21:00:00+09:00 存储为 2025-01-24T12:00:00.000Z。当值是日历日期或本地挂钟时间而非瞬间时,请改用 string 字段。
选择类型
select
从预定义选项中单选。
{
slug: "status",
label: "Status",
type: "select",
required: true,
defaultValue: "draft",
validation: {
options: ["draft", "published", "archived"],
},
}
验证选项:
options— 可选的允许值数组。提供它以展示预定义选项并拒绝其他字符串;不提供时,验证接受任意字符串。
存储为包含所选值的 TEXT。
multiSelect
从预定义选项中多选。
{
slug: "tags",
label: "Tags",
type: "multiSelect",
validation: {
options: ["news", "tutorial", "review", "opinion"],
},
}
验证选项:
options— 可选的允许值数组。提供它以展示预定义选项并拒绝其他字符串;不提供时,验证接受任意字符串数组。
存储为 JSON 数组:["news", "tutorial"]
富内容
portableText
使用 Portable Text 格式的富文本内容。支持标题、列表、链接、图片和自定义块。
{
slug: "content",
label: "Content",
type: "portableText",
required: true,
}
值存储为 Portable Text 块的 JSON 数组,例如:
[
{
"_type": "block",
"style": "normal",
"children": [{ "_type": "span", "text": "Hello world" }]
}
]
插件可以向编辑器添加自定义块类型(嵌入、小组件等)。它们出现在斜杠命令菜单中。在公开站点上渲染已保存的块需要来自原生插件或配套包的 Astro 组件。参见 Portable Text 渲染组件。
媒体类型
image
对已上传图片的引用。包含尺寸和替代文本等元数据。
{
slug: "featuredImage",
label: "Featured Image",
type: "image",
validation: {
allowedMimeTypes: ["image/jpeg", "image/png"],
},
options: {
darkVariant: true,
},
}
小组件选项:
darkVariant— 为编辑者提供第二个插槽,用于在深色配色方案中显示的图片(默认:false)。参见 Dark Mode。
验证选项:
allowedMimeTypes— 所选媒体接受的精确 MIME 类型的非空列表
值存储为带有媒体引用及其元数据的对象:
{
"id": "01HXK5MZSN...",
"src": "/_emdash/api/media/file/01HXK5MZSN...",
"alt": "Description",
"width": 1920,
"height": 1080,
"provider": "local",
"meta": {
"storageKey": "01HXK5MZSN....jpg"
}
}
启用 darkVariant 时,值可以在 darkVariant 下携带相同形状的深色对应项:
{
"id": "01HXK5MZSN...",
"alt": "Architecture diagram",
"width": 1920,
"height": 1080,
"darkVariant": {
"id": "01HXK5N2QT...",
"width": 1920,
"height": 1080
}
}
file
对已上传文件(如文档或 PDF)的引用。
{
slug: "document",
label: "Document",
type: "file",
validation: {
allowedMimeTypes: ["application/pdf"],
},
}
验证选项:
allowedMimeTypes— 所选媒体接受的精确 MIME 类型的非空列表
值存储为带有缓存元数据的提供方引用:
{
"id": "01HXK5MZSN...",
"provider": "local",
"filename": "report.pdf",
"mimeType": "application/pdf",
"meta": {
"storageKey": "01HXK5MZSN....pdf"
}
}
url 和 size 与其他缓存元数据字段一样是可选的。内容查询按原样返回
持久化值,不会从媒体库水合。需要最新元数据或提供方特定 URL 时,参见
文件值与当前元数据 了解
规范查询 API。
关系类型
reference
将条目链接到另一集合中的条目,并在管理端渲染为条目选择器。其 链接属于一个关系:一个连接两个集合、为每一侧命名并限制 每一侧可链接多少条目的模式对象。Relations 涵盖编辑者与管理端工作流。
以下字段将一篇文章链接到 authors 集合中的一个条目:
{
slug: "author",
label: "Author",
type: "reference",
required: true,
validation: {
targetCollection: "authors",
multiple: false,
},
}
验证:
targetCollection— 此字段链接到的集合的 slug。创建字段会为其创建 关系。multiple— 允许链接多个条目(默认:false)。仅与targetCollection一起阅读,因为限制随后属于新关系。relation— 要绑定到的现有关系的 slug,而不是创建新关系。relationSide— 此集合位于relation的哪一端,"parent"或"child"。仅对 两端为同一集合且两端匹配的关系设置。
提供 targetCollection 或 relation 之一。从 targetCollection 创建的字段成为名为
{collection}_{field} 的关系的父端,其子侧采用字段的标签,并且
除非设置了 multiple,否则持有一个条目。从 relation 创建的字段从其所在集合的那一端查看该关系,
另一端的集合是字段的目标。一个
关系每一端只接受一个字段,因此同一端上的第二个字段会被拒绝。两种形式都
在已创建的字段上存储 relation、relationSide 和 targetCollection,并且目标
集合此后固定:要更改它,请删除字段并添加新字段。重命名
字段会重命名它所查看的关系那一侧。
引用字段不会向集合表添加列。其链接位于
_emdash_content_references 中,按每个条目的翻译组键控,因此选择在
条目的翻译之间共享,而不是按语言环境设置。内容读取在按字段 slug 键控的
references 下返回链接的条目,而不是在 data 中。在模板中按名称请求字段 —
参见 读取引用字段。
绑定到关系的字段不能设置 indexed,因为它不存储可索引的列,并且站点
搜索也不覆盖它。
无关系的字段
既不指定关系也不指定目标集合的引用字段保留 TEXT 列,并
在其中保存一个条目 ID:
"01HXK5MZSN..."
设置了 options.allowMultiple 的字段在同一列中保存条目 ID 的 JSON 数组:
["01HXK5MZSN...", "01HXK6NATS..."]
该列像任何其他文本列一样读写,集合模式将
值验证为字符串,并且字段可以设置 indexed 并充当内容列表过滤器。它渲染为
文本框而不是选择器。
要将其变为选择器,在 Content Types 下打开该字段并选择一个被引用的集合。
EmDash 创建关系,将列中的条目 ID 复制为链接,并清除字段的
searchable 和 indexed 标志,因此内容列表过滤器和站点搜索不再覆盖它。
列仍留在原处并停止写入。Relations
从编辑者一侧涵盖相同步骤。
从较早版本更新的站点可能保留此状态的字段。参见 引用字段绑定到关系 了解更新绑定了什么以及留给你绑定什么。
灵活类型
json
任意 JSON 数据。用于复杂嵌套结构、第三方集成或没有固定模式的数据。
{
slug: "metadata",
label: "Metadata",
type: "json",
}
按原样存储在 SQLite JSON 列中。
repeater
结构化行的可重复列表。在 validation.subFields 中至少定义一个子字段;编辑者随后可以添加、移除、重新排序和编辑行,而无需输入原始 JSON。
以下字段存储产品规格列表:
{
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" },
],
},
}
Repeater 值存储为对象数组:
[
{
"label": "Weight",
"value": "1.2 kg",
"source": "https://example.com/specifications"
}
]
允许的子字段类型为 string、text、url、number、integer、boolean、datetime、select 和 image。Repeater 不能包含另一个 repeater 或 portableText、reference、file 等复杂字段。
Repeater 验证接受这些属性:
subFields— 一个或多个子字段定义。每个定义需要slug、label和type;也可以设置required。select子字段通过options提供其选项。minItems— 最小行数。必须为零或更大。maxItems— 最大行数。必须为一或更大,且不能小于minItems。
blocks
类型化内容块的有序列表。每种块类型有自己的字段并保留编号版本。在将它们添加到集合字段之前,通过模式 API、MCP 或种子文件定义块类型。
以下字段允许编辑者用英雄区和行动号召块组合页面:
{
slug: "layout",
label: "Layout",
type: "blocks",
validation: {
allowedTypes: ["hero", "call_to_action"],
maxItems: 20,
},
}
每个已存储的块在该版本声明的字段旁携带其类型、版本和稳定键:
[
{
"_type": "hero",
"_version": 1,
"_key": "01K5AB3F7M9QZ2X8W4V6T1R0YH",
"heading": "Bread made slowly, by hand."
}
]
Blocks 验证接受这些属性:
allowedTypes— 可供新块使用的有序块类型 slug。retiredTypes— 为已存储内容保留但对新块不可用的服务器管理块类型。minItems— 最小块数。在已有数据的集合上将其提高到零以上需要内容迁移。maxItems— 最大块数,最多 100。
blocks 字段是可选的,默认为空数组。它不能为 required、unique、searchable、indexed,也不能由自定义字段小组件渲染。块定义可以使用标量、文本、选择、Portable Text、图片、文件和 repeater 字段。它们不能包含引用、JSON、slug 或嵌套 blocks。
用 emdash/ui 的 <Blocks value components fallback> 渲染已存储的数组。种子、组件映射、缺失渲染器、激活和迁移示例见 用 blocks 构建页面。
字段属性
所有字段都支持这些通用属性:
| Property | Type | Description |
|---|---|---|
slug | string | 唯一标识符(必需) |
label | string | 显示名称(必需) |
type | FieldType | 字段类型(必需) |
required | boolean | 要求有值(默认:false) |
unique | boolean | 强制唯一性(默认:false) |
searchable | boolean | 将字段纳入全文搜索(默认:false) |
indexed | boolean | 启用索引排序/过滤 |
translatable | boolean | 按语言环境存储值(默认:true) |
defaultValue | unknown | 新条目的默认值 |
validation | object | 类型特定的验证规则 |
widget | string | 自定义小组件覆盖 |
options | object | 小组件配置 |
sortOrder | number | 管理端中的显示顺序 |
indexed 可用于标量字段:string、url、number、integer、boolean、
datetime、select、reference 和 slug。索引字段可作为内容列表查询中的 orderBy
字段传递,或用于 fieldFilters。避免索引不用于
排序或过滤的字段,因为每个索引都会增加存储和写入开销。
searchable 将字段的文本添加到集合的全文搜索索引。对标识符、价格、标志以及其他必须在条目的每次翻译中保持相同的值设置 translatable: false;当某个语言环境更改不可翻译字段时,EmDash 会将该值同步到其翻译条目。
blocks 类型仅使用此通用集合中的 slug、label、type、translatable、validation 和 sortOrder。其数组从不作为列必需,并且始终默认为 []。
保留的字段 slug
这些 slug 已保留,不能使用:
idslugstatusauthor_idprimary_byline_idcreated_atupdated_atpublished_atscheduled_atdeleted_atversionlive_revision_iddraft_revision_idtermsbylinesbyline
TypeScript 类型
导入字段类型定义以供编程使用:
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",
];