Content Models

Content models are the heart of DM Editors. They define the shape of every entry — fields, validation, defaults, and how content is exposed through the API.

Two flavors: collection vs single

Routes

RouteMethodPurpose
/admin/content-modelsGETList models
/admin/content-models/createGETNew model form
/admin/content-modelsPOSTCreate model
/admin/content-models/{content_model}/editGETEdit model + field builder
/admin/content-models/{content_model}PUTUpdate model
/admin/content-models/{content_model}DELETESoft delete (cascades to entries)
/admin/content-models/reorderPOSTDrag-and-drop reordering in sidebar
/admin/content-models/{content_model}/toggle-activePATCHActivate / deactivate
/admin/content-models/{content_model}/computed-fieldsPOSTSave computed-field definitions
/admin/content-models/{content_model}/test-computed-fieldPOSTTest a computed expression against a sample entry

Model attributes

AttributeNotes
nameDisplay name (e.g. "Blog Posts")
slugURL-friendly identifier (e.g. blog-posts) — used in routes and the API
name_singular / name_pluralUsed in UI labels
iconSidebar icon name
typecollection | single
is_singleConvenience boolean mirroring type
has_slugEnable per-entry slug field
has_timestampsShow created/updated on the entry list
has_publish_dateEnable published_at + scheduling
has_seoAdd the SEO sub-form (title, description, OG image)
title_fieldWhich field's value is treated as the entry title (default title)
is_localizedAllow per-locale entries
show_in_sidebarWhether the model appears in the admin nav
sort_orderPosition in the sidebar
settingsJSON — UI-level preferences
computed_fieldsJSON — array of computed field definitions
api_configJSON — public visibility, field allowlists, default sorts

Field builder

Each model has a list of content_fields built via drag-and-drop in the model editor. Each field has:

Available field types

TypeDescription
textSingle-line text input
textareaMulti-line text
richtextTipTap rich-text editor
markdownMarkdown editor with preview
numberNumeric input (int or float)
booleanToggle
date / datetimeDate pickers
select / multiselectPredefined option list
mediaSingle media picker (file UUID)
media_multiGallery — array of media UUIDs
relationReference another model's entries
repeaterRepeating field group
componentEmbed a defined component
dynamic_zoneEditor-chosen mix of components (Phase 2.5)
jsonRaw JSON editor
colorColor picker
url / email / phoneValidated text variants

Computed fields

Computed fields are server-evaluated values stored on each entry's computed_data JSON column. Definitions live on the model's computed_fields column and are re-evaluated on entry save. The test-computed-field endpoint lets you preview an expression against a sample entry before committing.

// Example computed_fields definition
[
  {
    "slug":   "reading_time",
    "label":  "Reading time (min)",
    "expr":   "ceil(word_count(data.body) / 200)"
  },
  {
    "slug":   "full_name",
    "label":  "Full name",
    "expr":   "data.first_name ~ ' ' ~ data.last_name"
  }
]

API exposure

A model's api_config column controls what is exposed at /api/v1/{slug} — visibility, allowed fields, default sort, default per-page. See API: Dynamic Content for endpoint details.

Deleting a modelSoft-deletes the model and cascades to all entries (via FK cascadeOnDelete). Restore by undeleting at the DB level; consider exporting first.