字段类型参考

本页内容

EmDash 支持 17 种用于定义内容模式的字段类型。每种类型对应一个 SQLite 列类型,并提供相应的管理 UI。

概览

下表列出每种字段类型及其 SQLite 列:

TypeSQLite ColumnDescription
stringTEXT短文本输入
textTEXT多行文本
urlTEXTURL 值
numberREAL小数
integerINTEGER整数
booleanINTEGER真/假
datetimeTEXT日期与时间
selectTEXT从选项中单选
multiSelectJSON多选
portableTextJSON富文本内容
imageTEXT图片引用
fileTEXT文件引用
referencenone链接到另一集合中的条目
jsonJSON任意 JSON 数据
slugTEXTURL 安全标识符
repeaterJSON可重复字段组
blocksJSON类型化页面组合

文本类型

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 构建页面。

字段属性

所有字段都支持这些通用属性:

PropertyTypeDescription
slugstring唯一标识符(必需)
labelstring显示名称(必需)
typeFieldType字段类型(必需)
requiredboolean要求有值(默认:false)
uniqueboolean强制唯一性(默认:false)
searchableboolean将字段纳入全文搜索(默认:false)
indexedboolean启用索引排序/过滤
translatableboolean按语言环境存储值(默认:true)
defaultValueunknown新条目的默认值
validationobject类型特定的验证规则
widgetstring自定义小组件覆盖
optionsobject小组件配置
sortOrdernumber管理端中的显示顺序

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 已保留,不能使用:

  • id
  • slug
  • status
  • author_id
  • primary_byline_id
  • created_at
  • updated_at
  • published_at
  • scheduled_at
  • deleted_at
  • version
  • live_revision_id
  • draft_revision_id
  • terms
  • bylines
  • byline

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",
];