Meridian handbook
For agentsRecipes

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.

A field is one value of a document: a number, a select, a relation, a photo, rich text. Fields are declared in the type’s schema file under config/schema/. Add them with engine-dmo dev field add; it writes the field with its id, checks the project and, with --apply, applies the schema.

Add a field

engine-dmo dev field add walk distanceKm --type number --label "Distance (km)" --param min=0 --apply
# written into config/schema/walk.yaml
  - { name: distanceKm, id: fld_azkam2rfyt, type: number, label: { en: Distance (km) }, min: 0 }
FlagEffect
--type <type>The field type. engine-dmo describe fieldtypes lists them: text, slug, number, money, boolean, select, date, datetime, recurrence, geo, geo_shape, address, phone, opening_hours, asset, link, video, relation, portable_text, blocks, repeater, seo, form
--label <text>The label in the source locale
--help-text <text>Help shown under the field in the editor
--requiredRequired at publish
--indexProjected for listing, filtering and sorting. Needed for query().where(), orderBy() and index page facets
--translate <mode>none, locale, language or group. Leave it out for the type’s default (describe fieldtypes shows it)
--options a,b,cA select’s option values, each given an id
--param key=valueAny parameter of the type, in YAML (max=280, multiline=true, to=area, multiple=true). Repeatable
--after <field>Place it after this field. On a core type it can name only a field of your own extends: file
--group <key>Put it in an editor group (dev group add makes one)
--site <key>A field only this site offers, on a shared type

A core type

On a core type (page, article, event, guide, collection, listing, area) the verb writes an extends: file the first time:

engine-dmo dev field add page contactForm --type form --label "Form on this page" --apply
# config/schema/page.yaml
extends: page
fields:
  - { name: contactForm, id: fld_n65eek1b0r, type: form, label: { en: Form on this page } }

An extends: file adds fields after the core ones; it cannot remove or change them. --after title on a core type exits 3 with --after names "title", which is not a field in schema/page.yaml: a core field cannot be an anchor. The core fields of each type are in Core types; engine-dmo describe type page lists them marked core. The core page has only title and slug, so most sites add a summary and a body first:

engine-dmo dev field add page summary --type text --param multiline=true --param max=280 --label Summary --apply
engine-dmo dev field add page body --type portable_text --label Body --apply

A select with labelled options

--options gives values without labels, and a template printing .label then shows the raw value. Give each option a label: start the field with one option, add the rest with dev option add --label, then add label: to the first option by hand, keeping its id:

engine-dmo dev field add walk difficulty --type select --options easy --label Difficulty --required --index --apply
engine-dmo dev option add walk difficulty moderate --label Moderate --apply
engine-dmo dev option add walk difficulty hard --label Hard --apply

Do not skip the hand edit: check does not warn about an option with no label at all (only about a label that lacks a locale), and the facet and .label then print easy. The result, after label: { en: Easy } is added to the first option by hand:

  - { name: difficulty, id: fld_8tvr5aq659, type: select, label: { en: Difficulty }, required: true, index: true, options: [{ value: easy, id: opt_z9ynd1s738, label: { en: Easy } }, { value: moderate, id: opt_9kkqg3nqew, label: { en: Moderate } }, { value: hard, id: opt_c5mcqxkfct, label: { en: Hard } }] }

A select needs at least one option: dev field add ... --type select without --options is refused.

A relation

engine-dmo dev field add walk startsAt --type relation --param to=page --param multiple=true --label "Starts at" --apply
  - { name: startsAt, id: fld_2bptk4rq2s, type: relation, label: { en: Starts at }, to: page, multiple: true }

Add --index when pages will query by it (query('walk').where('startsAt', entry)). See Relations.

A boolean filter

engine-dmo dev field add walk accessible --type boolean --index --label "Step-free" --after difficulty --apply

Change a field

engine-dmo dev field set walk distanceKm --param max=100 --apply
engine-dmo dev field set walk distanceKm --help-text "Round to one decimal place" --apply

dev field set --label replaces the whole label map with the source locale’s label, dropping its translations. On a multilingual project, change a label by editing the YAML instead.

Rename a field

engine-dmo dev field rename walk distanceKm lengthKm --apply

The handle changes, the id and every stored value stay, and the old handle stays as an alias (aliases: [distanceKm]) so templates keep working. check then warns at each template still using the old handle; update them and retire the alias with engine-dmo schema alias retire walk.distanceKm. --no-alias drops the alias at once.

Remove a field

engine-dmo dev field remove walk accessible --apply

Values stay stored under the field’s id (kept under _orphaned), and the plan says how many documents hold one. If any do, the plan is destructive: --apply exits 2 and a person must approve it with engine-dmo schema apply --allow-destructive. Remove every template use of the field first, or check fails.

dev field remove cannot edit a field written in block style (one key per line); it reports the edit would not parse. Delete those lines from the YAML by hand, then run engine-dmo check and engine-dmo schema plan.

Verify

engine-dmo check
engine-dmo schema plan
engine-dmo describe type walk

Then render a page that prints the field: engine-dmo render /walks/cherwell-towpath --json. A field added after content exists is empty on every document until edited or reseeded; a new --required field blocks publishing those documents until it is filled.