This guide covers advanced schema configuration techniques, validation rules, and best practices for creating robust content schemas in md0 CMS.
Schema Structure
A complete schema configuration includes:
fields:
- name: title # Field identifier
label: "Post Title" # Display label
type: string # Field type
required: true # Validation
default: "" # Default value
description: "..." # Help text
placeholder: "..." # Input placeholder
Field Configuration Options
Universal Options
Available for all field types:
name: field_name # Required: unique identifier
label: "Display Label" # Optional: shown in UI
type: string # Required: field type
required: true # Optional: validation
default: value # Optional: default value
description: "Help text" # Optional: helper
hidden: false # Optional: hide from UI
Type-Specific Options
String Fields
name: slug
type: string
minLength: 3
maxLength: 100
pattern: "^[a-z0-9-]+$"
placeholder: "my-post-slug"
Options:
minLength: Minimum character countmaxLength: Maximum character countpattern: Regex validation patternplaceholder: Input placeholder text
Text Fields
name: description
type: text
minLength: 50
maxLength: 500
rows: 5
placeholder: "Enter description..."
Options:
minLength: Minimum character countmaxLength: Maximum character countrows: Number of visible rowsplaceholder: Placeholder text
Number Fields
name: price
type: number
min: 0
max: 10000
step: 0.01
placeholder: "0.00"
Options:
min: Minimum valuemax: Maximum valuestep: Increment step (0.01 for decimals)placeholder: Placeholder text
Boolean Fields
name: featured
type: boolean
default: false
trueLabel: "Featured"
falseLabel: "Not Featured"
Options:
default: Default value (true/false)trueLabel: Label for true statefalseLabel: Label for false state
Date/DateTime Fields
name: published_at
type: datetime
format: "YYYY-MM-DD HH:mm:ss"
default: now
min: "2020-01-01"
max: "2030-12-31"
Options:
format: Date format stringdefault: Default value (nowor date string)min: Minimum allowed datemax: Maximum allowed date
Array Fields
name: tags
type: array
items: string
minItems: 1
maxItems: 10
default: []
Options:
items: Type of array itemsminItems: Minimum number of itemsmaxItems: Maximum number of itemsdefault: Default array value
Select Fields
name: status
type: select
options:
- label: "Draft"
value: draft
- label: "Published"
value: published
- label: "Archived"
value: archived
default: draft
Options:
options: Array of choicesdefault: Default selected value
Image Fields
name: cover_image
type: image
folder: "/public/images"
maxSize: 5242880 # 5MB in bytes
allowedTypes:
- image/jpeg
- image/png
- image/webp
Options:
folder: Upload destinationmaxSize: Maximum file size in bytesallowedTypes: Allowed MIME types
Object Fields
name: author
type: object
fields:
- name: name
type: string
required: true
- name: email
type: string
pattern: "^[^@]+@[^@]+\\.[^@]+$"
- name: bio
type: text
Options:
fields: Array of nested field definitions
Validation Patterns
Common Regex Patterns
Slug validation:
pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
# Lowercase letters, numbers, hyphens
# Example: my-post-slug
Email validation:
pattern: "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
# Basic email format
# Example: user@example.com
URL validation:
pattern: "^https?://[^\\s]+$"
# HTTP or HTTPS URLs
# Example: https://example.com
Alphanumeric only:
pattern: "^[a-zA-Z0-9]+$"
# Letters and numbers only
# Example: abc123
Date format (YYYY-MM-DD):
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
# Example: 2024-01-15
Phone number (US):
pattern: "^\\(?\\d{3}\\)?[- ]?\\d{3}[- ]?\\d{4}$"
# Example: (555) 123-4567
Hex color:
pattern: "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"
# Example: #FF5733 or #F57
Schema Templates
Blog Post Schema
fields:
- name: title
type: string
required: true
maxLength: 100
placeholder: "Post title"
- name: slug
type: string
required: true
pattern: "^[a-z0-9-]+$"
description: "URL-friendly version of title"
- name: date
type: date
required: true
default: now
- name: excerpt
type: text
required: true
minLength: 50
maxLength: 200
placeholder: "Brief summary (50-200 characters)"
- name: author
type: string
required: true
default: "Admin"
- name: tags
type: array
items: string
minItems: 1
maxItems: 5
- name: category
type: select
required: true
options:
- Tutorial
- Guide
- News
- Case Study
- name: featured_image
type: image
folder: "/public/images/posts"
maxSize: 2097152 # 2MB
- name: published
type: boolean
default: false
- name: seo
type: object
fields:
- name: meta_title
type: string
maxLength: 60
- name: meta_description
type: text
maxLength: 160
- name: keywords
type: array
items: string
Documentation Schema
fields:
- name: title
type: string
required: true
- name: description
type: text
required: true
maxLength: 300
- name: category
type: select
options:
- Getting Started
- Guides
- API Reference
- Examples
- name: order
type: number
default: 0
min: 0
description: "Order in navigation"
- name: last_updated
type: date
default: now
- name: contributors
type: array
items: string
- name: difficulty
type: select
options:
- Beginner
- Intermediate
- Advanced
- name: related_docs
type: array
items: string
description: "Related documentation slugs"
Product Schema
fields:
- name: name
type: string
required: true
- name: sku
type: string
required: true
pattern: "^[A-Z0-9-]+$"
- name: description
type: text
required: true
- name: price
type: number
required: true
min: 0
step: 0.01
- name: sale_price
type: number
min: 0
step: 0.01
- name: images
type: array
items: image
minItems: 1
- name: category
type: select
required: true
options:
- Electronics
- Clothing
- Books
- Home & Garden
- name: in_stock
type: boolean
default: true
- name: stock_quantity
type: number
min: 0
default: 0
- name: specifications
type: object
fields:
- name: weight
type: string
- name: dimensions
type: string
- name: color
type: string
- name: material
type: string
Conditional Fields
Show fields based on other field values:
- name: content_type
type: select
options:
- Article
- Video
- Podcast
- name: video_url
type: string
condition:
field: content_type
equals: Video
- name: podcast_url
type: string
condition:
field: content_type
equals: Podcast
- name: duration
type: number
condition:
field: content_type
in:
- Video
- Podcast
Field Groups
Organize related fields together:
- name: basic_info
type: group
label: "Basic Information"
fields:
- name: title
type: string
- name: description
type: text
- name: seo_settings
type: group
label: "SEO Settings"
collapsed: true
fields:
- name: meta_title
type: string
- name: meta_description
type: text
- name: og_image
type: image
- name: advanced
type: group
label: "Advanced Options"
collapsed: true
fields:
- name: custom_css
type: text
- name: custom_js
type: text
Default Values
Static Defaults
- name: author
type: string
default: "Admin"
- name: published
type: boolean
default: false
- name: tags
type: array
default: []
Dynamic Defaults
- name: date
type: date
default: now # Current date/time
- name: year
type: number
default: "{{year}}" # Current year
- name: author
type: string
default: "{{user.name}}" # Current user's name
Custom Validation
Custom Validation Functions
- name: email
type: string
validate: |
function(value) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!emailRegex.test(value)) {
return "Please enter a valid email address"
}
return true
}
Multi-Field Validation
- name: end_date
type: date
validate: |
function(value, fields) {
if (value < fields.start_date) {
return "End date must be after start date"
}
return true
}
Schema Best Practices
Naming Conventions
# Use snake_case for field names
featured_image # Good
featuredImage # Avoid (camelCase)
featured-image # Avoid (kebab-case)
# Use clear, descriptive names
title # Good
t # Bad
post_title # Acceptable but redundant
Required Fields
Only mark truly essential fields as required:
# Good: Essential fields only
- title (required)
- date (required)
- content (required via markdown body)
# Avoid: Too many required fields
- title (required)
- excerpt (required)
- author (required)
- tags (required)
- category (required)
- image (required)
Field Ordering
Order fields logically:
# Good order
1. title # Most important first
2. slug # Related to title
3. date # Publication info
4. author # Author info
5. excerpt # Content preview
6. tags # Organization
7. category # Organization
8. featured_image # Media
9. published # Status last
# Poor order (random)
1. published
2. featured_image
3. title
4. tags
Descriptions and Help Text
Provide clear guidance:
# Good
description: "Brief summary shown in post listings (50-200 characters)"
# Bad
description: "Description field"
Troubleshooting
Schema Not Saving
Check:
- Valid YAML syntax
- No duplicate field names
- Field types are supported
- No circular dependencies
Validation Not Working
Check:
- Regex pattern is escaped properly
- Min/max values are appropriate
- Required fields are marked correctly
- Custom validation functions are error-free
Fields Not Displaying
Check:
- Field name doesn't conflict with reserved words
- Field type is supported
- No conditional logic hiding field
- Schema is saved and published
Next Steps
- Create Collections with your schema
- Start Editing content
- Integrate with Your Site