Add a content type
How an agent adds a custom content type to a Meridian project with dev type add and dev field add, what the generated schema file holds, and how to verify the type is applied and has an id for every field.
A content type is a kind of document (a walk, an event, a news story) with its own fields. Core types (page, article, event, guide, collection, and with engine-dmo listing and area) already exist; add a custom type only when none of them fits, and extend a core type when it nearly does (see Add a field).
Steps
Check the name is free and see what exists:
engine-dmo describe project --json Add the type. It gets title, slug (generated from the title) and summary:
engine-dmo dev type add walk --label Walk --plural Walks --apply wrote config/schema/walk.yaml
...
+ type walk custom, 3 fields
+ field walk.title text
+ field walk.slug slug
+ field walk.summary text
Plan: 3 add field, 1 add type.
applied Without a database, leave out --apply; the file is still written and checked.
Add its fields, one verb each. Look up a type’s parameters with engine-dmo describe fieldtypes --json first:
engine-dmo dev field add walk distanceKm --type number --label "Distance (km)" --param min=0 --apply
engine-dmo dev field add walk difficulty --type select --options easy,moderate,hard --label Difficulty --required --index --apply
engine-dmo dev field add walk photo --type asset --label Photo --apply
engine-dmo dev field add walk body --type portable_text --label "Route description" --apply --index is what lets a listing page filter or sort on the field. --required makes the field required at publish.
Read the result:
# config/schema/walk.yaml
key: walk
id: typ_bm5h7rk9j6
label: { en: Walk }
plural: { en: Walks }
ordering: { field: title, direction: asc }
fields:
- { name: title, id: fld_4crq7vfgva, type: text, required: true, index: true }
- { name: slug, id: fld_hbjpyckec7, type: slug, source: title, required: true }
- { name: summary, id: fld_96fyjc4qs9, type: text, multiline: true, max: 280 }
- { name: distanceKm, id: fld_azkam2rfyt, type: number, label: { en: Distance (km) }, min: 0 }
- { name: difficulty, id: fld_8tvr5aq659, type: select, label: { en: Difficulty }, required: true, index: true, options: [{ value: easy, id: opt_z9ynd1s738 }, { value: moderate, id: opt_9kkqg3nqew }, { value: hard, id: opt_c5mcqxkfct }] }
- { name: photo, id: fld_crnr761s22, type: asset, label: { en: Photo } }
- { name: body, id: fld_yms2apxswc, type: portable_text, label: { en: Route description } } Your ids will differ: they are minted for your project. Never copy these.
Give the type a route and templates: Add a route and its template.
Writing the file by hand
When you need options the verbs do not offer (option labels, editor groups, structured_data, validation rules), write the schema file yourself without ids and let the engine add them:
# config/schema/walk.yaml
key: walk
label: { en: Walk }
plural: { en: Walks }
fields:
- { name: title, type: text, required: true, index: true }
- { name: slug, type: slug, source: title, required: true }
- { name: summary, type: text, multiline: true, max: 280 } engine-dmo check --fix check --fix writes typ_ and fld_ ids into the file, keeping your comments. Content types lists every key a type file takes.
Verify
engine-dmo check
engine-dmo schema plan # exits 0, "No changes", after apply
engine-dmo describe type walk describe type prints every field with its id and its translate mode (translate locale for text that differs per locale, translate none for values shared by every locale).
Options of dev type add
| Flag | Effect |
|---|---|
--label <name> | The type’s name in the source locale |
--plural <name> | Its plural, used as the index page’s title |
--site <key> | A type of one site only, in that site’s schema directory |
--sites <a,b> | Limit a shared type to these sites |
--dry-run | Print the diff, write nothing |
--apply | Apply the schema plan when it is not destructive |
The type key is lowercase letters, digits and underscores (walk, tour_operator); tourOperator and tour-operator are refused. Field names may be camel case (distanceKm). Field names id, type, uri, url, status, locale, tags, seo, noindex, author, organisation, createdAt, updatedAt, publishedAt, redirectFrom and translations are reserved.
Recipes
Complete, checked examples of the tasks an agent meets most when building a Meridian site, from adding a content type to a DMO directory, a partner portal and an extension, each with the commands, the files and how to verify them.
Add a field
How an agent adds, labels, changes, renames and removes fields on custom and core Meridian types, including select options with labels, relations and boolean filters, with the commands, the YAML they write and the pitfalls of each verb.