Content Modelling
Design structured content models for reusable, multi-channel content.
When to Use / Not Use
Use when:
- Designing a CMS schema for a new project
- Defining content types with fields, constraints, and relationships
- Planning editorial workflows (draft, review, publish, archive)
- Building multi-channel content systems (web, mobile, email, API)
- Migrating from page-based to structured content models
- Establishing naming conventions for content types and fields
Do NOT use when:
- Building formal ontologies with classes, properties, and inference rules -> use
ontology-design
- Standardizing naming conventions across code and documentation -> use
consistency-standards
- Designing API schemas and endpoints -> use
api-design
Decision Tree
What are you modeling?
├── CMS content types (what fields, what relationships)
│ ├── New system? -> Start with content inventory, then type design (§Field Types, §Relationship Types)
│ └── Existing system with problems? -> Audit for anti-patterns first (§Anti-Patterns)
├── Multi-channel publishing (same content, different outputs)
│ └── Need COPE? -> Use semantic fields, not layout fields (§Design Principles)
├── Editorial workflow (who reviews, when, how)
│ └── Need lifecycle model? -> Define status enum + transition rules (§Content Model Template)
├── Terminology standardization (what to call things)
│ └── Naming conventions only? -> Use `consistency-standards` instead
└── Formal knowledge model with reasoning?
└── Use `ontology-design` instead
Core Concepts
| Concept |
Definition |
| Content Type |
Template defining structure for similar content |
| Field |
Single data element within a content type |
| Relationship |
Connection between content types |
| Instance |
Specific piece of content based on a type |
Field Types
| Type |
Use Case |
Example |
| Short text |
Titles, labels |
"Getting Started" |
| Long text |
Descriptions |
Paragraph content |
| Rich text |
Formatted content |
Bold, links, lists |
| Number |
Quantities |
42 |
| Boolean |
Toggles |
true |
| Date |
Timestamps |
2024-01-15 |
| Media |
Images, files |
hero.png |
| Reference |
Links to other content |
→ Author |
| Enum |
Fixed choices |
`draft |
Relationship Types
Reference (Linked)
Content exists independently, linked by ID.
Article → Author (reference)
└─ Author can be edited separately
Embedded
Content nested within parent.
Article ⊃ SEO Metadata (embedded)
└─ Metadata only exists in this article
Hierarchical
Parent-child relationships.
Documentation
├── Getting Started
│ ├── Installation
│ └── Configuration
└── API Reference
Relationship Decision Guide
| Question |
If Yes |
If No |
| Does the related content exist independently? |
Use Reference |
Use Embedded |
| Will it be edited in one place and propagate? |
Use Reference |
Use Embedded |
| Is it a tree structure? |
Use Hierarchical |
— |
Content Model Template
## Content Type: [Name]
### Overview
| Attribute | Value |
|-----------|-------|
| **Purpose** | [what this type represents] |
| **Cardinality** | [expected instance count] |
| **Lifecycle** | [draft → review → published] |
### Fields
| Field | Type | Required | Constraints |
|-------|------|----------|-------------|
| title | Short text | Yes | Max 100 chars |
| slug | Short text | Yes | URL-safe, unique |
| body | Rich text | Yes | - |
| author | Reference | Yes | → Author |
| status | Enum | Yes | draft/published |
### Relationships
| Relation | Type | Target | Cardinality |
|----------|------|--------|-------------|
| author | Reference | Author | 1:1 |
| category | Reference | Category | Many:1 |
### Validation Rules
- `slug` must be unique within parent
- `publishedAt` required when `status = published`
Naming Conventions
| Element |
Convention |
Example |
| Types |
PascalCase |
BlogPost |
| Fields |
camelCase |
publishedAt |
| Slugs |
kebab-case |
getting-started |
Design Principles
COPE: Create Once, Publish Everywhere
- Separate content from presentation
- Use semantic fields, not layout fields
- Enable multi-channel delivery
Atomic Content
- Break content into smallest reusable units
- Compose complex content from atoms
- Avoid duplication
Anti-Patterns
| Anti-Pattern |
Problem |
Solution |
| Page-based models |
Content tied to specific layouts; cannot reuse across channels |
Redesign with semantic fields; remove all layout-specific fields (heroImage position, sidebar width) from content types |
| HTML in rich text fields |
Content renders incorrectly on mobile or in email; mixes content with presentation |
Enforce rich text fields as semantic markup only; strip layout HTML in migration; use structured blocks |
| Monolithic content type |
One "General Content" type with 40 optional fields; authors confused about which to fill |
Decompose into specific types based on field usage analysis; each type gets only its relevant fields |
| Redundant fields |
Same data in multiple places; drift on updates |
Single-source via references or variables; if data changes, update once |
| Missing lifecycle |
Content jumps from draft to published with no review; stale content never archived |
Add status enum with transition rules and required review steps |
| Presentation in model |
heroImage on a Guide type that not all channels render |
Move to separate MediaAsset reference; rendering layer decides what to show |
1---2name: content-modelling3description: Design CMS content models — content types, fields, editorial workflows, governance rules, and COPE (Create Once, Publish Everywhere) patterns — for structured, multi-channel publishing. Use when the user asks to design a content model, define content types in a CMS, structure fields for editorial content, plan a headless CMS architecture, or design content reuse across channels. NOT for formal knowledge graphs, OWL/RDF ontologies, or semantic modeling (use ontology-design). NOT for naming conventions or taxonomy standards across code (use consistency-standards).4---56# Content Modelling78Design structured content models for reusable, multi-channel content.910## When to Use / Not Use1112**Use when:**13- Designing a CMS schema for a new project14- Defining content types with fields, constraints, and relationships15- Planning editorial workflows (draft, review, publish, archive)16- Building multi-channel content systems (web, mobile, email, API)17- Migrating from page-based to structured content models18- Establishing naming conventions for content types and fields1920**Do NOT use when:**21- Building formal ontologies with classes, properties, and inference rules -> use `ontology-design`22- Standardizing naming conventions across code and documentation -> use `consistency-standards`23- Designing API schemas and endpoints -> use `api-design`2425## Decision Tree2627```28What are you modeling?29├── CMS content types (what fields, what relationships)30│ ├── New system? -> Start with content inventory, then type design (§Field Types, §Relationship Types)31│ └── Existing system with problems? -> Audit for anti-patterns first (§Anti-Patterns)32├── Multi-channel publishing (same content, different outputs)33│ └── Need COPE? -> Use semantic fields, not layout fields (§Design Principles)34├── Editorial workflow (who reviews, when, how)35│ └── Need lifecycle model? -> Define status enum + transition rules (§Content Model Template)36├── Terminology standardization (what to call things)37│ └── Naming conventions only? -> Use `consistency-standards` instead38└── Formal knowledge model with reasoning?39 └── Use `ontology-design` instead40```4142## Core Concepts4344| Concept | Definition |45|---------|------------|46| **Content Type** | Template defining structure for similar content |47| **Field** | Single data element within a content type |48| **Relationship** | Connection between content types |49| **Instance** | Specific piece of content based on a type |5051## Field Types5253| Type | Use Case | Example |54|------|----------|---------|55| Short text | Titles, labels | "Getting Started" |56| Long text | Descriptions | Paragraph content |57| Rich text | Formatted content | Bold, links, lists |58| Number | Quantities | `42` |59| Boolean | Toggles | `true` |60| Date | Timestamps | `2024-01-15` |61| Media | Images, files | `hero.png` |62| Reference | Links to other content | → Author |63| Enum | Fixed choices | `draft|published` |6465## Relationship Types6667### Reference (Linked)68Content exists independently, linked by ID.69```70Article → Author (reference)71 └─ Author can be edited separately72```7374### Embedded75Content nested within parent.76```77Article ⊃ SEO Metadata (embedded)78 └─ Metadata only exists in this article79```8081### Hierarchical82Parent-child relationships.83```84Documentation85├── Getting Started86│ ├── Installation87│ └── Configuration88└── API Reference89```9091### Relationship Decision Guide9293| Question | If Yes | If No |94|----------|--------|-------|95| Does the related content exist independently? | Use Reference | Use Embedded |96| Will it be edited in one place and propagate? | Use Reference | Use Embedded |97| Is it a tree structure? | Use Hierarchical | — |9899## Content Model Template100101```markdown102## Content Type: [Name]103104### Overview105| Attribute | Value |106|-----------|-------|107| **Purpose** | [what this type represents] |108| **Cardinality** | [expected instance count] |109| **Lifecycle** | [draft → review → published] |110111### Fields112| Field | Type | Required | Constraints |113|-------|------|----------|-------------|114| title | Short text | Yes | Max 100 chars |115| slug | Short text | Yes | URL-safe, unique |116| body | Rich text | Yes | - |117| author | Reference | Yes | → Author |118| status | Enum | Yes | draft/published |119120### Relationships121| Relation | Type | Target | Cardinality |122|----------|------|--------|-------------|123| author | Reference | Author | 1:1 |124| category | Reference | Category | Many:1 |125126### Validation Rules127- `slug` must be unique within parent128- `publishedAt` required when `status = published`129```130131## Naming Conventions132133| Element | Convention | Example |134|---------|------------|---------|135| Types | PascalCase | `BlogPost` |136| Fields | camelCase | `publishedAt` |137| Slugs | kebab-case | `getting-started` |138139## Design Principles140141### COPE: Create Once, Publish Everywhere142- Separate content from presentation143- Use semantic fields, not layout fields144- Enable multi-channel delivery145146### Atomic Content147- Break content into smallest reusable units148- Compose complex content from atoms149- Avoid duplication150151## Anti-Patterns152153| Anti-Pattern | Problem | Solution |154|---|---|---|155| Page-based models | Content tied to specific layouts; cannot reuse across channels | Redesign with semantic fields; remove all layout-specific fields (heroImage position, sidebar width) from content types |156| HTML in rich text fields | Content renders incorrectly on mobile or in email; mixes content with presentation | Enforce rich text fields as semantic markup only; strip layout HTML in migration; use structured blocks |157| Monolithic content type | One "General Content" type with 40 optional fields; authors confused about which to fill | Decompose into specific types based on field usage analysis; each type gets only its relevant fields |158| Redundant fields | Same data in multiple places; drift on updates | Single-source via references or variables; if data changes, update once |159| Missing lifecycle | Content jumps from draft to published with no review; stale content never archived | Add status enum with transition rules and required review steps |160| Presentation in model | `heroImage` on a Guide type that not all channels render | Move to separate MediaAsset reference; rendering layer decides what to show |