craft-content-modeling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCraft CMS 5 — Content Modeling
Craft CMS 5 — 内容建模
How to structure content in Craft CMS 5. Sections, entry types, fields, Matrix,
relations, asset management, and strategic patterns for real projects.
This skill covers content architecture — what goes in the CP, how it's
organized, and how templates access it. For extending Craft with PHP
(plugins, modules, custom element types), see the skill. For Twig
template patterns, see and .
craftcmscraft-sitecraft-twig-guidelines如何在 Craft CMS 5 中搭建内容结构。涵盖 Sections、entry types、fields、Matrix、关联关系、资源管理,以及适用于实际项目的策略模式。
本技能覆盖内容架构相关内容——控制面板(CP)中包含什么、如何组织,以及模板如何访问这些内容。如果要使用 PHP 扩展 Craft(插件、模块、自定义元素类型),请参考 技能。如果需要 Twig 模板相关的模式,请参考 和 。
craftcmscraft-sitecraft-twig-guidelinesDocumentation
文档
- Entries: https://craftcms.com/docs/5.x/reference/element-types/entries.html
- Sections: https://craftcms.com/docs/5.x/reference/element-types/entries.html#sections
- Fields: https://craftcms.com/docs/5.x/system/fields.html
- Field types: https://craftcms.com/docs/5.x/reference/field-types/
- Matrix: https://craftcms.com/docs/5.x/reference/field-types/matrix.html
- Relations: https://craftcms.com/docs/5.x/system/relations.html
- Eager loading: https://craftcms.com/docs/5.x/development/eager-loading.html
- Project config: https://craftcms.com/docs/5.x/system/project-config.html
Use on specific doc pages when a reference file doesn't cover enough detail.
web_fetch- 条目:https://craftcms.com/docs/5.x/reference/element-types/entries.html
- Sections:https://craftcms.com/docs/5.x/reference/element-types/entries.html#sections
- 字段:https://craftcms.com/docs/5.x/system/fields.html
- 字段类型:https://craftcms.com/docs/5.x/reference/field-types/
- Matrix:https://craftcms.com/docs/5.x/reference/field-types/matrix.html
- 关联关系:https://craftcms.com/docs/5.x/system/relations.html
- 预加载:https://craftcms.com/docs/5.x/development/eager-loading.html
- 项目配置:https://craftcms.com/docs/5.x/system/project-config.html
当参考文件没有覆盖足够细节时,可以对特定文档页面使用 工具获取内容。
web_fetchThe Craft 5 Mental Model
Craft 5 核心设计理念
Everything is an entry. Entry types are global (shared across sections and
Matrix fields). Fields come from a global pool. Categories, tags, and globals
are being phased out — use entries instead.
Three decisions define your content architecture:
- Which section type organizes the content (Single, Channel, Structure)
- Which entry types define its shape (global, reusable across contexts)
- Which relation strategy connects content together (Entries fields, Matrix, or both)
所有内容都是条目。 Entry type 是全局的(在 sections 和 Matrix 字段之间共享)。字段来自全局字段池。分类、标签和全局变量正在逐步淘汰——请改用条目。
三个决策决定了你的内容架构:
- 使用哪种 section 类型来组织内容(Single、Channel、Structure)
- 使用哪些 entry type来定义内容结构(全局、可跨场景复用)
- 使用哪种关联策略来连接内容(条目字段、Matrix,或两者结合)
Section Type Decision
Section 类型选择指南
| Need | Section Type | URI Example |
|---|---|---|
| One-off page (homepage, about, contact) | Single | |
| Site-wide settings (footer, header config) | Single (no URI, | — |
| Flat collection (blog, news, events) | Channel | |
| Hierarchical pages (docs, services) | Structure | |
| Taxonomy (topics, categories) | Structure (replaces categories) | |
| Flat tags | Channel (replaces tags) | — |
| 需求 | Section 类型 | URI 示例 |
|---|---|---|
| 单页页面(首页、关于页、联系页) | Single | |
| 全站设置(页脚、头部配置) | Single(无URI,开启 | — |
| 扁平集合(博客、新闻、活动) | Channel | |
| 层级页面(文档、服务) | Structure | |
| 分类体系(主题、分类) | Structure(替代原有分类功能) | |
| 扁平标签 | Channel(替代原有标签功能) | — |
Singles replace globals
Singles 替代全局变量
Set in to access singles as global
Twig variables by handle — identical to the old globals behavior but with drafts,
revisions, live preview, and scheduling.
preloadSingles => trueconfig/general.phptwig
{# With preloadSingles enabled #}
{{ siteSettings.footerText }}
{{ siteSettings.socialLinks.all() }}Caveat: Singles always propagate to all sites. This is hard-coded.
在 中设置 ,即可通过 handle 将 singles 作为全局 Twig 变量访问——和旧的全局变量行为完全一致,但额外支持草稿、修订版、实时预览和定时发布功能。
config/general.phppreloadSingles => truetwig
{# 开启 preloadSingles 后即可使用 #}
{{ siteSettings.footerText }}
{{ siteSettings.socialLinks.all() }}注意: Singles 会默认传播到所有站点,这是硬编码的逻辑。
Structure queries for navigation
用于导航的 Structure 查询
twig
{% set topLevel = craft.entries.section('pages').level(1).all() %}
{% set children = craft.entries.descendantOf(entry).descendantDist(1).all() %}
{% set breadcrumbs = craft.entries.ancestorOf(entry).all() %}
{% set siblings = craft.entries.siblingOf(entry).all() %}twig
{% set topLevel = craft.entries.section('pages').level(1).all() %}
{% set children = craft.entries.descendantOf(entry).descendantDist(1).all() %}
{% set breadcrumbs = craft.entries.ancestorOf(entry).all() %}
{% set siblings = craft.entries.siblingOf(entry).all() %}Entry Types in Craft 5
Entry Types in Craft 5
Entry types are defined globally (Settings → Entry Types), then attached to
sections and Matrix fields. One entry type can serve multiple contexts.
Key implications:
- Changing an entry type's field layout affects every section and Matrix field using it
- Fields come from the global pool — same field definition reused everywhere
- Local name/handle overrides per context available (5.6.0+)
- The global pool demands careful field naming — use specific handles
Entry type 是全局定义的(设置 → Entry Types),之后可以关联到 sections 和 Matrix 字段。同一个 entry type 可以在多个场景下使用。
核心影响:
- 修改一个 entry type 的字段布局会影响所有使用它的 section 和 Matrix 字段
- 字段来自全局字段池——同一个字段定义可以在所有地方复用
- 支持在不同场景下覆盖名称/handle(5.6.0及以上版本支持)
- 全局字段池要求字段命名要谨慎——使用明确的 handle
Reserved handles (will collide with native attributes)
保留 handle(会和原生属性冲突)
titleslugiduiddateCreateddateUpdatedstatusurlurienabledarchivedsiteIdlevellftrgtrootpostDateexpiryDatetitleslugiduiddateCreateddateUpdatedstatusurlurienabledarchivedsiteIdlevellftrgtrootpostDateexpiryDateCommon Pitfalls
常见误区
- Over-using Matrix — if content needs its own URL, independent querying, or permissions, it should be a separate section with an Entries relation field, not a Matrix block.
- Vague field handles — ,
image,textcollide fast in the global pool. Uselink,blogFeaturedImage,serviceDescription.ctaLink - Not planning multi-site from the start — propagation method, field translation methods, and site settings must be configured before content exists. Changing propagation later resaves all entries.
- Using categories/tags in new projects — they're deprecated. Use Structure sections (hierarchical taxonomy) and Channel sections (flat taxonomy) with Entries fields.
- Forgetting — without it, singles aren't available as global variables and you need explicit queries.
preloadSingles - Matrix for everything — 15+ entry types in one Matrix field is a red flag. Deeply nested Matrix hits limits and degrades CP performance.
max_input_vars - Not using — every relational field access inside a loop should use
.eagerly()to prevent N+1 queries..eagerly() - Editing project config YAML manually — let Craft manage . Use
config/project/to regenerate from DB if needed.php craft project-config/rebuild - Using database IDs in URI formats — IDs differ across environments. Use ,
{slug}, or custom fields.{canonicalUid} - Not setting in production — without this, production schema changes won't sync back to dev.
allowAdminChanges => false
- 过度使用 Matrix——如果内容需要独立URL、独立查询或者权限控制,它应该是一个独立的 section,通过条目关联字段关联,而不是放在 Matrix 块中。
- 字段 handle 命名模糊——、
image、text这类命名在全局字段池中很容易冲突。请使用link、blogFeaturedImage、serviceDescription这类命名。ctaLink - 一开始没有规划多站点功能——传播方式、字段翻译方法、站点设置必须在内容录入前配置完成。之后修改传播方式会导致所有条目重新保存。
- 在新项目中使用分类/标签——这两个功能已经废弃。请使用 Structure section(层级分类)和 Channel section(扁平分类)搭配条目字段。
- 忘记开启 ——不开启的话,singles 不能作为全局变量使用,你需要显式写查询语句获取。
preloadSingles - 所有内容都用 Matrix——一个 Matrix 字段里有15个以上的 entry type 是危险信号。深度嵌套的 Matrix 会触发 限制,降低控制面板的性能。
max_input_vars - 不使用 ——循环中每次访问关联字段都应该使用
.eagerly()来避免N+1查询问题。.eagerly() - 手动编辑项目配置YAML文件——让 Craft 自行管理 目录。如有需要,可以使用
config/project/从数据库重新生成配置。php craft project-config/rebuild - 在URI格式中使用数据库ID——不同环境的ID不一致。请使用 、
{slug}或者自定义字段。{canonicalUid} - 生产环境没有设置 ——不设置的话,生产环境的 schema 变更无法同步回开发环境。
allowAdminChanges => false
Reference Files
参考文件
Read the relevant reference file(s) for your task.
Task examples:
- "Plan a blog content architecture" → read
content-patterns.md - "Which field type should I use for X?" → read
field-types.md - "Set up relatedTo queries" → read
relations-and-eager-loading.md - "Configure Matrix with nested entries" → read (Matrix section)
field-types.md - "Plan a multi-site content model" → read + propagation in SKILL.md
content-patterns.md - "Understand project config workflow" → this SKILL.md covers the essentials
| Reference | Scope |
|---|---|
| All 26 built-in field types: settings, Twig access patterns, query syntax, gotchas. Matrix configuration, view modes, nesting. |
| relatedTo() shapes (4 forms), .with() eager loading, .eagerly() lazy eager loading, nested eager loading, native eager-loadable attributes. |
| Strategic patterns for blog, portfolio, multi-site corporate, e-commerce. Section/field/relation architecture per pattern. Categories-to-entries migration. |
根据你的任务阅读对应的参考文件。
任务示例:
- "规划博客内容架构" → 阅读
content-patterns.md - "X场景应该用哪种字段类型?" → 阅读
field-types.md - "设置 relatedTo 查询" → 阅读
relations-and-eager-loading.md - "配置带嵌套条目的 Matrix" → 阅读 (Matrix部分)
field-types.md - "规划多站点内容模型" → 阅读 + SKILL.md中的传播相关内容
content-patterns.md - "了解项目配置工作流" → 本SKILL.md已经覆盖了核心要点
| 参考文件 | 覆盖范围 |
|---|---|
| 全部26种内置字段类型:设置、Twig访问模式、查询语法、注意事项。Matrix配置、视图模式、嵌套。 |
| relatedTo() 的4种写法、.with()预加载、.eagerly()懒预加载、嵌套预加载、原生可预加载属性。 |
| 博客、作品集、多站点企业站、电商的策略模式。每种模式对应的section/field/关联架构。分类转条目的迁移方法。 |
Propagation Methods (Multi-Site)
传播方法(多站点)
Available for channels and structures. Singles always propagate to all sites.
| Method | Behavior |
|---|---|
| Only save to site created in | Entries exist in one site only |
| Same site group | Entries propagate within the same site group |
| Same language | Entries propagate to sites sharing the same language |
| All enabled sites | Entries exist in all enabled sites (default) |
| Let each entry choose | Per-entry control via Status sidebar |
Matrix fields have their own propagation method, independent of the section's.
适用于 channel 和 structure。Singles 总是会传播到所有站点。
| 方法 | 行为 |
|---|---|
| 仅保存到创建时的站点 | 条目仅存在于单个站点 |
| 同一站点组 | 条目在同一个站点组内传播 |
| 同一语言 | 条目传播到使用相同语言的站点 |
| 所有已启用站点 | 条目存在于所有已启用站点(默认) |
| 每个条目自行选择 | 通过状态侧边栏为每个条目单独设置 |
Matrix 字段有自己独立的传播方法,和所属 section 的传播方法无关。
Field Translation Methods
字段翻译方法
Per-field setting controlling how values behave across sites:
| Method | Behavior |
|---|---|
| Not translatable | Same value across all sites |
| Per site | Independent value per site |
| Per site group | Shared within site group, independent across groups |
| Per language | Shared across sites with same language |
| Custom | User-defined grouping key |
Configure translation methods before populating content.
每个字段的设置,控制字段值在不同站点间的行为:
| 方法 | 行为 |
|---|---|
| 不可翻译 | 所有站点使用相同的值 |
| 按站点区分 | 每个站点的值独立 |
| 按站点组区分 | 站点组内共享,不同组之间独立 |
| 按语言区分 | 使用相同语言的站点共享值 |
| 自定义 | 用户自定义分组key |
请在录入内容之前配置翻译方法。
Project Config Essentials
项目配置核心要点
All schema changes (sections, entry types, fields, volumes, transforms, sites,
plugins, permissions) are stored as YAML in .
config/project/所有 schema 变更(sections、entry types、fields、资源卷、转换规则、站点、插件、权限)都以 YAML 格式存储在 目录下。
config/project/Workflow
工作流
- Make CP changes in development environment
- YAML auto-updates in
config/project/ - Commit to Git
- Deploy to staging/production
- Run (applies migrations + project config)
ddev craft up
- 在开发环境的控制面板中做修改
- 下的YAML文件会自动更新
config/project/ - 提交到Git
- 部署到预发布/生产环境
- 运行 (应用迁移 + 项目配置)
ddev craft up
Rules
规则
- Never manually edit YAML — let Craft manage it
- Always set in production
allowAdminChanges => false - Use UIDs (not IDs) — they're stable across environments
- After resolving Git merge conflicts in YAML: then
ddev craft project-config/touchddev craft project-config/apply - Use syntax in YAML for environment-specific values
$ENV_VAR
- 永远不要手动编辑YAML——让Craft自行管理
- 生产环境务必设置
allowAdminChanges => false - 使用UID(而不是ID)——它们在不同环境之间是稳定的
- 解决YAML的Git合并冲突后:执行 然后执行
ddev craft project-config/touchddev craft project-config/apply - 在YAML中使用 语法来定义环境特定的值
$ENV_VAR
Asset Volumes and Transforms
资源卷和图片转换
Volumes define content organization. Filesystems define storage (local, S3,
Google Cloud, Azure). Multiple volumes can share one filesystem.
资源卷定义内容的组织方式。文件系统定义存储位置(本地、S3、Google Cloud、Azure)。多个资源卷可以共享同一个文件系统。
Image Transforms
图片转换
twig
{# Named transform (defined in Settings → Assets → Image Transforms) #}
<img src="{{ asset.getUrl('thumb') }}" alt="{{ asset.alt }}">
{# Ad-hoc transform #}
{% set transform = { width: 300, height: 200, mode: 'crop', format: 'webp' } %}
<img src="{{ asset.getUrl(transform) }}" alt="{{ asset.alt }}">
{# Srcset #}
{{ asset.getImg({ width: 300 }, ['1.5x', '2x', '3x']) }}Always add the Alternative Text field layout element to asset volumes for
accessibility.
twig
{# 命名转换规则(在 设置 → 资源 → 图片转换 中定义) #}
<img src="{{ asset.getUrl('thumb') }}" alt="{{ asset.alt }}">
{# 临时转换规则 #}
{% set transform = { width: 300, height: 200, mode: 'crop', format: 'webp' } %}
<img src="{{ asset.getUrl(transform) }}" alt="{{ asset.alt }}">
{# Srcset #}
{{ asset.getImg({ width: 300 }, ['1.5x', '2x', '3x']) }}请务必在资源卷的字段布局中添加替代文本字段,以满足无障碍要求。