内容类型建模Skill content-type-modeling

该技能专注于设计 headless CMS 中的内容类型架构,用于定义可重用的内容部分和字段组合,优化跨通道内容交付。关键词:内容建模、headless CMS、内容架构、可重用性、组合模式、API 设计。

架构设计 0 次安装 0 次浏览 更新于 3/11/2026

name: content-type-modeling description: 当设计内容类型层次结构、定义可重用的内容部分或为 headless CMS 结构化字段组合时使用。涵盖了内容类型 -> 内容部分 -> 内容字段的层次模式、内容类型继承、组合与继承的权衡以及跨通道最大可重用性的模式设计。 allowed-tools: Read, Glob, Grep, Task, Skill, AskUserQuestion

内容类型建模

交互式建模配置

使用 AskUserQuestion 来配置内容类型建模会话:

# 问题 1: 建模范围 (MCP: CMS 内容架构模式)
question: "您需要什么内容类型建模?"
header: "范围"
options:
  - label: "单一类型(推荐)"
    description: "设计一个带有部分和字段的内容类型"
  - label: "类型家族"
    description: "共享公共部分的相关内容类型"
  - label: "完整分类法"
    description: "带有关系的完整内容模型"
  - label: "迁移"
    description: "从传统内容迁移到结构化内容"

# 问题 2: 可重用性策略 (MCP: Orchard Core 内容模式)
question: "内容部分应如何结构化?"
header: "重用"
options:
  - label: "组合(推荐)"
    description: "从可重用部分构建类型 - 最大灵活性"
  - label: "继承"
    description: "带有专门扩展的基础类型"
  - label: "混合"
    description: "组合和继承的混合"
  - label: "扁平"
    description: "每个类型上的独立字段 - 没有共享部分"

使用这些响应来确定建模范围和组合策略。

设计 headless CMS 架构的内容类型层次结构、可重用部分和字段组合的指导。

何时使用此技能

  • 为新 CMS 设计内容类型模式
  • 定义跨多个类型的可重用内容部分
  • 结构化自定义字段组合
  • 规划内容类型继承策略
  • 从传统内容迁移到结构化内容
  • 创建多通道内容架构

三级层次结构

Headless CMS 平台通常使用三级内容层次结构,灵感来自 Orchard Core 和类似平台:

内容类型(例如,“博客文章”、“产品”、“事件”)
├── 内容部分(可重用的字段组)
│   ├── TitlePart(标题,显示标题)
│   ├── AutoroutePart(slug,URL 模式)
│   ├── PublishLaterPart(计划发布)
│   └── [自定义部分]
└── 内容字段(个别数据元素)
    ├── TextField(单行,多行)
    ├── HtmlField(富文本)
    ├── MediaField(图像,文档)
    ├── ContentPickerField(引用)
    └── [自定义字段]

内容类型

内容类型是内容项的蓝图。它们定义了可用的部分和字段。

content_type:
  name: BlogPost
  display_name: Blog Post
  description: 带有作者和类别的博客文章
  stereotype: Content  # Content, Widget, MenuItem
  creatable: true
  listable: true
  draftable: true
  versionable: true
  securable: true

关键决策:

| 决策 | 选项 | 推荐 | | 命名 | 单数 vs 复数 | 单数(BlogPost,不是 BlogPosts) | | 刻板印象 | Content, Widget, MenuItem | Content 用于独立,Widget 用于可嵌入 | | 可起草 | true/false | true 用于编辑内容 | | 可版本化 | true/false | true 用于审计要求 |

内容部分

内容部分是可重用的字段组,可以附加到多个内容类型。它们促进 DRY 原则。

content_part:
  name: SeoMetaPart
  description: 搜索引擎的 SEO 元数据
  fields:
    - name: MetaTitle
      type: TextField
      settings:
        max_length: 60
        hint: "搜索结果显示的标题"
    - name: MetaDescription
      type: TextField
      settings:
        max_length: 160
        editor: TextArea
    - name: MetaKeywords
      type: TextField
      settings:
        editor: TextArea
        hint: "逗号分隔的关键词"
    - name: NoIndex
      type: BooleanField
      settings:
        default: false

常见可重用部分:

| 部分 | 目的 | 附加到 | | TitlePart | 标题和显示标题 | 所有内容类型 | | AutoroutePart | URL slug 生成 | 页面,文章 | | PublishLaterPart | 计划发布 | 编辑内容 | | LocalizationPart | 多语言支持 | 可翻译内容 | | SeoMetaPart | 搜索引擎元数据 | 公共页面 | | CommonPart | 所有者,创建/修改日期 | 所有内容类型 | | ContainablePart | 父容器引用 | 层次内容 |

内容字段

内容字段是附加到部分或直接附加到内容类型的个别数据元素。

标准字段类型:

| 字段类型 | 目的 | 示例使用 | | TextField | 单行/多行文本 | 标题,描述 | | HtmlField | 带格式的富文本 | 主体内容 | | NumericField | 数字(整数,小数) | 价格,数量 | | BooleanField | 真/假切换 | 特色,已发布 | | DateTimeField | 日期和/或时间 | 事件日期,截止日期 | | MediaField | 图像,文档,视频 | 英雄图像,附件 | | ContentPickerField | 引用其他内容 | 作者,相关文章 | | TaxonomyField | 类别/标签选择 | 类别,标签 | | LinkField | 带有可选文本的 URL | 外部链接 | | UserPickerField | 引用用户 | 作者,分配者 |

组合与继承

组合模式(推荐)

通过组合部分来构建内容类型。这是灵活性的首选方法。

# 博客文章 = TitlePart + AutoroutePart + BodyPart + SeoMetaPart + 自定义字段
content_type:
  name: BlogPost
  parts:
    - TitlePart
    - AutoroutePart
    - PublishLaterPart
    - SeoMetaPart
  fields:
    - name: FeaturedImage
      type: MediaField
    - name: Author
      type: ContentPickerField
      settings:
        content_types: [Author]
    - name: Categories
      type: TaxonomyField
      settings:
        taxonomy: BlogCategories

好处:

  • 部分可跨类型重用
  • 对部分的更改影响所有附加类型
  • 清晰的关注点分离
  • 更容易添加/删除功能

继承模式

谨慎使用于真正的“是-a”关系。

# 基础类型
content_type:
  name: Article
  abstract: true  # 不能直接创建实例
  parts:
    - TitlePart
    - AutoroutePart
    - BodyPart

# 派生类型
content_type:
  name: NewsArticle
  extends: Article
  fields:
    - name: BreakingNews
      type: BooleanField

content_type:
  name: OpinionPiece
  extends: Article
  fields:
    - name: OpinionAuthor
      type: ContentPickerField

何时使用继承:

  • 清晰的“是-a”关系
  • 跨子类型共享行为
  • 需要多态查询
  • 有限层次深度(最多2-3层)

字段设计最佳实践

命名约定

做:
- PascalCase 用于类型/部分/字段名称:BlogPost, FeaturedImage
- 描述性名称指示目的:PublishDate(不是 Date1)
- 一致的后缀:*Date, *Image, *List
不做:
- 缩写:PubDt, FeatImg
- 通用名称:Data, Value, Field1
- 不一致的大小写:blogPost, featured_image

字段验证

field:
  name: Email
  type: TextField
  validation:
    required: true
    pattern: "^[^@]+@[^@]+\\.[^@]+$"
    max_length: 255
    unique: true  # 在内容类型内
  settings:
    placeholder: "user@example.com"
    hint: "输入有效的电子邮件地址"

必需与可选字段

必需字段:
- 内容有意义所必需的
- 用于 URL 或标识
- API 消费者需要
可选字段:
- 增强功能或元数据
- 可能不适用于所有实例
- 编辑器中逐步披露

内容类型类别

系统内容类型

内置类型,支持 CMS 功能:

| 类型 | 目的 | | Menu | 导航结构 | | MenuItem | 个别菜单链接 | | Taxonomy | 类别/标签词汇表 | | TaxonomyTerm | 个别术语 | | MediaAsset | 图像,文档 | | User | 用户资料 |

常见内容类型

跨 CMS 项目经常需要:

# Page - 通用内容页面
content_type:
  name: Page
  parts: [TitlePart, AutoroutePart, BodyPart, SeoMetaPart]
  fields:
    - name: FeaturedImage
      type: MediaField
      optional: true

# Article - 博客文章,新闻文章
content_type:
  name: Article
  parts: [TitlePart, AutoroutePart, BodyPart, SeoMetaPart, PublishLaterPart]
  fields:
    - name: Author
      type: ContentPickerField
    - name: FeaturedImage
      type: MediaField
    - name: Categories
      type: TaxonomyField
    - name: Tags
      type: TaxonomyField
    - name: ReadTime
      type: NumericField
      computed: true

# Event - 日历事件
content_type:
  name: Event
  parts: [TitlePart, AutoroutePart, BodyPart]
  fields:
    - name: StartDate
      type: DateTimeField
      required: true
    - name: EndDate
      type: DateTimeField
    - name: Location
      type: TextField
    - name: VirtualLink
      type: LinkField
    - name: RegistrationUrl
      type: LinkField

API 考虑

内容类型到 API 形状

内容类型应清晰地映射到 API 响应:

{
  "id": "abc123",
  "contentType": "BlogPost",
  "displayText": "我的博客文章标题",
  "createdUtc": "2025-01-15T10:30:00Z",
  "modifiedUtc": "2025-01-15T14:22:00Z",
  "publishedUtc": "2025-01-15T14:22:00Z",
  "owner": "user123",
  "parts": {
    "TitlePart": {
      "title": "我的博客文章标题"
    },
    "AutoroutePart": {
      "path": "/blog/我的博客文章标题"
    }
  },
  "fields": {
    "FeaturedImage": {
      "paths": ["/media/hero.jpg"],
      "alt": "英雄图像"
    },
    "Author": {
      "contentItemIds": ["author456"]
    },
    "Categories": {
      "termIds": ["cat1", "cat2"]
    }
  }
}

GraphQL 模式生成

内容类型通常映射到 GraphQL 类型:

type BlogPost implements ContentItem {
  contentItemId: ID!
  contentType: String!
  displayText: String
  createdUtc: DateTime
  publishedUtc: DateTime

  # 部分
  titlePart: TitlePart
  autoroutePart: AutoroutePart

  # 字段
  featuredImage: MediaField
  author: ContentPickerField
  categories: TaxonomyField
}

迁移策略

从传统到结构化

1. 审计现有内容
   - 记录当前结构
   - 识别重复模式
   - 注意关系

2. 设计目标模式
   - 将字段分组到部分
   - 定义内容类型
   - 规划分类法

3. 创建映射
   - 旧字段 -> 新字段
   - 需要的数据转换
   - 新字段的默认值

4. 增量迁移
   - 从简单类型开始
   - 每批后验证
   - 保持旧系统并行运行

内容类型检查清单

在最终确定内容类型之前:

  • [ ] 清晰、描述性的名称
  • [ ] 适当的部分附加
  • [ ] 所有必要的字段定义
  • [ ] 验证规则指定
  • [ ] 必需与可选明确标记
  • [ ] API 形状考虑
  • [ ] 本地化要求解决
  • [ ] 搜索索引配置
  • [ ] 预览/显示模板规划
  • [ ] 编辑体验优化

相关技能

  • dynamic-schema-design - EF Core JSON 列用于自定义字段
  • content-relationships - 内容项之间的引用
  • content-versioning - 草稿/发布和版本历史
  • taxonomy-architecture - 类别和标签
  • headless-api-design - 内容交付 API