Content Type
Content Type 是内容所遵循的模板(schema). 它定义了内容拥有哪些字段, 以及每个字段的类型, 是否多语言, 是否必填, 以及校验规则. 以服装购物商城的 "商品" 为例, 商品名, 价格, 详细说明, 主图这样的项目构成由一个 Content Type "商品" 来规定, 而实际的每个商品则作为遵循该模板的 Content 创建.
在 CMA 中, Content Type 是 Space 的下级资源, 其路径以 /spaces/{spaceId}/content-types 为基准. 创建, 修改, 取消发布等管理操作在 CMA 中执行, 已发布的快照通过 CDA 进行传递. 但 Content Type 在创建, 修改时会自动发布, 因此与 Content 不同, 无需单独的发布调用即可立即进入 Published 状态(参见下文状态与自动发布).
资源结构
下面是 Content Type "商品" 的单个查询响应. 它带有 sys(系统属性), 以及 name, displayField, publishWithAuthor, fields 等正文属性.
{
"sys": {
"id": "3trmXRLdJF4GBlAjtcuoZ7Pnxj8dlA",
"type": "ContentType",
"space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
"publish": {
"version": 7,
"at": "2026-06-17T03:13:49.973Z",
"firstAt": "2026-06-14T17:04:46.953Z",
"counter": 4,
"by": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } }
},
"createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
"createdAt": "2026-06-14T17:04:46.846Z",
"updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
"updatedAt": "2026-06-17T03:13:49.973Z",
"version": 8,
"status": "Published"
},
"name": "商品",
"displayField": "productName",
"publishWithAuthor": false,
"fields": [
{ "id": "5n06s7ocmwdi", "name": "商品名称", "apiName": "productName", "type": "ShortText", "localized": true, "required": true, "validations": [], "disabled": false },
{ "id": "1gecyz8g4llwf", "name": "价格", "apiName": "price", "type": "Long", "localized": false, "required": false, "validations": [], "disabled": false },
{ "id": "3ow4popgz54zg", "name": "详细说明", "apiName": "description", "type": "RichText", "localized": true, "required": false, "validations": [], "disabled": false },
{ "id": "2alxdptmdub1s", "name": "主图", "apiName": "photo", "type": "Refer", "localized": false, "required": false, "validations": [], "disabled": false, "targetType": "Media" },
{
"id": "2a80lehazfx3t",
"name": "品牌",
"apiName": "brand",
"type": "Refer",
"localized": false,
"required": false,
"validations": [
{ "referContentType": [ { "sys": { "id": "3trmXRM3RqbgSnifyg7OveRYWnJWEG", "type": "Refer", "targetType": "ContentType" } } ] }
],
"disabled": false,
"targetType": "Content"
}
]
}主要的键:
sys.id: Content Type 的唯一标识符. 它会填入单个查询, 修改, 删除路径中的{contentTypeId}.name: Content Type 的名称(例如商品).displayField: 在内容工作室列表中代表展示每个 Content 的字段的apiName(例如productName).publishWithAuthor: 发布 Content 时是否在发布快照中一并包含作者信息(sys.createdBy,sys.updatedBy). 默认值为false, 此时通过 CDA/ACDA 传递的快照中不包含作者. 该值在发布时刻生效且不追溯, 因此即使之后改为true, 已发布的 Content 也需要重新发布才会填入作者. 管理 API(CMA/ACMA)所处理的草稿中无论此设置如何都带有sys.createdBy. 若要在传递响应中暴露作者(byline), 或在 CDA/ACDA 中判定权限规则的createdBy过滤器(含:self), 则须将此值设为true(参见 SpaceRole 和 ServiceUserRole 的createdBy过滤器说明).fields: 该模板所定义的字段列表. 每一项的结构在下文字段中说明.
photo 字段的 type 为 Refer 且 targetType 为 Media, 因此指向上传的文件资产. brand 字段为 Refer + targetType: Content, 并通过 validations 中的 referContentType 限制为只能引用特定 Content Type(此处为 "品牌")的 Content.
系统属性 (sys)
每个 Content Type 都在 sys 对象中携带公共系统属性以及 Content Type 专有属性. space, createdBy, updatedBy 以 Refer 形态({ "sys": { "id", "type": "Refer", "targetType" } })填入.
| 属性 | 类型 | 说明 |
|---|---|---|
id | string | 资源唯一标识符. |
type | string | 资源种类. Content Type 始终为 "ContentType". |
space | Refer<Space> | 该 Content Type 所属的 Space. |
createdBy | Refer<User> | 创建者. |
createdAt | string (date-time) | 创建时间. |
updatedBy | Refer<User> | 最后修改者. |
updatedAt | string (date-time) | 最后修改时间. |
version | integer (≥1) | 资源版本. 创建, 修改, 发布, 取消发布等每次变更都会加 1. |
status | string (enum) | 发布状态. 为 Draft, Changed, Published, Archived 之一. |
publish | object | 发布历史. 参见下方的键. |
publish 对象的键:
| 键 | 类型 | 说明 |
|---|---|---|
version | integer | 最后一次发布时刻的 sys.version. |
at | string (date-time) | 最后一次发布时间. |
firstAt | string (date-time) | 首次发布时间. 即使取消发布也会保留. |
counter | integer | 累计发布次数. |
by | Refer<User> | 最后一次发布者. |
取消发布(DELETE .../publish)后, publish 中的 version, at, by 会被移除, 只保留 firstAt, counter.
Content Type 的 sys 中没有 Content 的 sys 所具有的 contentType(自引用)属性. 这是因为 Content Type 本身就是模板. 它也没有 archive 属性.
字段
fields 是该 Content Type 所定义字段的列表. 每一项具有如下结构(FieldDefinition).
| 键 | 类型 | 说明 |
|---|---|---|
id | string (1-64) | 字段的唯一标识符. 创建时自动分配. |
name | string (1-50) | 在内容工作室中显示的字段名称(例如 商品名称). |
apiName | string (1-64) | 在 API 中指代该字段的键. 模式 ^[a-zA-Z0-9][a-zA-Z0-9-_]*$(以英文, 数字开头, 之后为英文, 数字, -, _). |
type | string (enum) | 字段的类型. 参见下文字段种类 (type). |
localized | boolean | 是否可以拥有多语言值. |
required | boolean | 是否必填. |
validations | array | 应用于值的校验规则列表. 没有规则时为空数组 []. 参见下文校验 (validations). |
disabled | boolean | 是否停用. |
targetType | string (enum) | 仅当 type 为 Refer 时. 引用对象是 Content 还是 Media. |
items | object | 仅当 type 为 Array 时. 数组元素的定义(Refer 元素或 ShortText 元素). |
字段种类 (type)
type 决定值被存储, 查询的方式. 部分类型的检索行为不同.
type | 含义 | 值限制 | 备注 |
|---|---|---|---|
ShortText | 短的单行文本. | 64 字符 | 适合精确关键词查询. |
LongText | 较长的正文文本. | 5,120 字符 | 支持全文(full-text)相似度检索. |
RichText | 带格式的正文. | 204,800 字符 | 不作为检索对象, 用于格式表现. |
Long | 整数. | 例如价格 price. | |
Number | 实数(含小数). | 仅限有限值 | 不接受无穷大与 NaN. |
Boolean | 真/假. | ||
Date | 日期, 时间. | ||
Json | 任意 JSON 结构. | 序列化后 5,120 字符 | 结构内部的数字也必须是有限值. |
Location | 位置(坐标). | latitude -90longitude -180 | |
Refer | 指向其他资源的引用. | 通过 targetType 指定 Content 或 Media. | |
Array | 容纳多个值的数组. | 64 个元素 | 通过 items 附带元素定义. |
在 "商品" 示例中, 商品名称 为 ShortText, 价格 为 Long, 详细说明 为 RichText, 主图 为 Refer(targetType: Media), 品牌 为 Refer(targetType: Content).
值限制是由类型规定的平台上限,它不在创建 Content Type 时检查,而在向 Content 写入值时检查。即使在 validations 的 size 中写入比它更大的上限,也会先触发平台上限。Array 的元素同样直接适用元素类型的相同限制,因此 items.type 为 ShortText 的数组,每个元素都不能超过 64 字符。用超出限制的值写入 Content 时请求会被拒绝,其错误码见 Content 的错误。
校验 (validations)
validations 是应用于字段值的规则数组. 每一项携带下列键之一.
| 键 | 形态 | 说明 |
|---|---|---|
size | { "min", "max" } | 文本长度或数组大小的最小, 最大值. |
unique | boolean | 禁止在同一 Content Type 内出现重复值. |
regexp | { "pattern", "flags" } | 值必须与正则表达式模式匹配. pattern 必填. |
prohibitRegexp | { "pattern", "flags" } | 值若与正则表达式模式匹配则拒绝. pattern 必填. |
in | array | 允许值列表. 只有列表中的值才能通过. |
range | { "min", "max" } | 数字值的最小, 最大值. |
dateRange | { "min", "max", "after", "before" } | 日期值的允许范围. |
mediaMimetypeGroup | array | Refer(Media)字段中允许的文件类型列表. 参见下方 enum. |
mediaImageDimensions | { "width", "height" } | 图像的宽, 高像素约束. |
mediaFileSize | { "min", "max" } | 文件大小(字节)的最小, 最大值. |
referContentType | array | Refer(Content)字段中允许引用的 Content Type 列表. 每一项为 Refer<ContentType> 形态. |
message | string | 校验失败时显示的自定义消息. |
mediaMimetypeGroup 可用的值(12 种): Attachment, Plaintext, Image, Audio, Video, RichText, Presentation, Spreadsheet, PdfDocument, Archive, Code, Markup.
"商品" 示例的 brand 字段通过 referContentType 限制为只能引用 "品牌" Content Type(其 sys.id 为 3trmXRM3RqbgSnifyg7OveRYWnJWEG).
状态与自动发布
Content Type 在创建, 修改, 部分修改时会自动发布. 这一点与 Content 不同. Content 在创建后需要单独的发布调用才能进入传递路径, 而 Content Type 的创建响应会直接返回 status: "Published".
status 为下列 4 种之一.
status | 含义 |
|---|---|
Draft | 未发布的状态. |
Changed | 曾经发布过, 但之后的变更尚未发布的状态. |
Published | 已发布且没有未发布变更的状态. |
Archived | 已归档的状态. |
sys.version 在每次变更时加 1. 由于 Content Type 的修改与发布会一次性发生, 因此一次修改会使 version 增加 2(修改本身 +1, 自动发布 +1). 在示例 "公告" 中, 创建之后 version 为 2(创建 +1, 自动发布 +1), publish.counter 为 1. 随后修改时 version 变为 4, publish.counter 变为 2.
Content Type 进入 Draft 的唯一途径是显式取消发布(DELETE .../publish). 取消发布后 status 变为 Draft, 并且 publish 对象中去掉 version, at, by, 只保留 firstAt, counter.
约束
| 对象 | 约束 |
|---|---|
name(Content Type) | 1-64 字, 必填. |
description | 128 字以内, 可选. |
fields | 1-80 个. 创建, 修改, 部分修改都必须遵守该范围. |
name(字段) | 1-50 字, 必填. |
apiName(字段) | 1-64 字, 模式 ^[a-zA-Z0-9][a-zA-Z0-9-_]*$, 必填. |
删除守护: 删除必须同时满足两个条件.
- 只要存在任何一个使用该 Content Type 的 Content, 就无法删除. 请先删除所有相关的 Content. 这项检查最先触发.
- 处于发布状态(
Published,Changed)的 Content Type 无法直接删除. 请先取消发布(DELETE .../publish)使其变为Draft后再删除(Archived状态也可删除).
错误
以下是处理 Content Type 时会遇到的错误码。所有资源共通的错误码,请参见通用错误。
| 错误码 | 条件 |
|---|---|
WGL422010 | 在仍有 Content 使用该 Content Type 的状态下,试图删除该 Content Type。取消发布也会经过同样的检查,因此只要还有 Content 使用该 Content Type,取消发布的请求就会先以该错误码被拒绝。 |
WGL422009 | 没有先取消发布,就试图删除处于发布状态(Published·Changed)的 Content Type。 |
WGL422006 | 试图取消发布并非处于发布状态的 Content Type。 |
WGL400002 | fields 的个数超出了允许范围。创建、修改、部分修改都会经过该个数检查。 |
WGL400045 | displayField 中填写的值,在该 Content Type 的 fields 所含的 apiName 中找不到。 |
WGL400046 | 必须一并填写配套属性的字段缺少该属性。Array 需要 items,Refer 需要 targetType。 |
WGL400040 | 有两个以上的字段使用了相同的 apiName。 |
API
下面所有端点的基准 URL 为 https://cma.weegloo.com/v1, 并且 Authorization 头需要用于 CMA 认证的 Bearer 令牌. 修改, 部分修改, 发布, 取消发布为了乐观并发控制, 需要一并发送 X-Weegloo-Version 头(当前资源的 sys.version).
相关文档
- Content 建模: 在内容工作室中创建 Content Type 的方法.
- 状态与发布: 发布, 版本的含义.
