Fields
The keys every field takes (name, type, label, required, index, translate, visible_when and the rest), field groups, and a table of all 23 field types with links to each type's page.
A field is one entry in a type’s fields: list. Every field has a name and a type; the other keys below are common to all field types, and any key that is not one of them is a parameter of the field type, checked against that type’s parameter list.
fields:
- name: distanceKm # the handle templates and the API use
type: number # one of the field types below
label: { en-GB: Distance }
help: { en-GB: The length of the whole route. }
required: true # needed to publish
index: true # projected for filtering and sorting
min: 0.1 # number parameters
max: 200
unit: km Keys every field takes
| Key | Type | Default | What it does |
|---|---|---|---|
name | string | required | The handle: a lowercase letter then letters and digits (distanceKm, heroImage). Unique within its level of the type. Templates read it as entry.<name>. |
type | string | required | A field type from the table below. |
id | string | written by check --fix | The field’s stable id, fld_ and ten characters. Never written by hand; it is what keeps values through a rename. |
label | locale map or string | the name | The editor’s label. |
help | locale map or string | One line of guidance under the control. | |
required | boolean | false | The field must have a value to publish. A draft saves without it. See Validation. |
required_in | source, all, a locale code, or a list of them | [source] | With required: true, which locales must have the value to publish. |
required_when | expression | Required to publish when the expression is true (Validation). | |
visible_when | expression | Shown in the editor only when the expression is true; a hidden field’s value is dropped on save. | |
recommended | boolean | false | Advice only: an empty recommended field blocks nothing and lowers the page’s content health score. |
index | boolean | false | Projects the value into the query index, so lists, smart lists, filters and ordering can filter and sort by it. Inside a repeater or blocks field, a child with index: true is projected under a dotted key (stages.distanceKm). |
unique | boolean | false | No two documents of the type may hold the same value (per locale for a translated field). Top-level text, slug, number, select, phone and date fields only. A warning on save, an error at publish. |
protected | boolean | false | Any change to the field’s storage (type, translate mode, parameters) or its removal is destructive in a schema plan, even when no document holds a value (Schema changes). |
translate | none, locale, language or group | per type, see below | How many values the field has across locales (Localisation). |
translatable | boolean | Shorthand: true is translate: locale, false is translate: none. | |
structure | shared or per_locale | shared | Repeater, blocks, link, asset and video fields: whether the item list is shared by every locale or each locale’s own (Localisation). |
fallback | empty or inherit | empty | On the public site, what a locale without its own value shows: nothing, or the source locale’s value. |
site_overridable | boolean | false | Top-level fields only: a site the document is shared to may hold its own value of this field. Not on slug, not inside a container. |
aliases | list of names | Old handles of a renamed field, still answered by templates and the content API with a warning until retired (Schema changes). | |
machine_translate | allow or forbid | allow | forbid stops AI drafting a translation of this field. Has no effect without an AI provider. |
summary_of | field name | On a top-level text field: AI summarisation drafts it from the named top-level text or portable_text field. Has no effect without an AI provider. | |
default | any | Recorded with the field. It is used when an older revision, written before the field existed, is restored. The editor does not prefill it on a new document. | |
personal | boolean | false | Only for custom fields of a person record in config/crm/person.yaml (engine-dmo): included in a subject access export and cleared by an erasure. On a document type it fails check. |
fields | list | The child fields of a repeater, or the sub-fields of every link of a link field. | |
blocks | list | The blocks of a blocks field, or the object blocks of a portable_text field. | |
use | field group name | Includes a field group instead of declaring a field (Field groups). |
A field may sit inside a repeater item or a block; the same keys apply there except site_overridable, unique and summary_of, which are top-level only.
Field types
engine-dmo describe fieldtypes lists these with every parameter; --json gives the same as data. Both bundles have the same field types.
| Type | Stores | Default translate | Projected with index: true | Page |
|---|---|---|---|---|
text | a string | locale | the string | Text and slug |
slug | a URL segment, per locale | locale | the string | Text and slug |
number | a number | none | the number | Numbers and money |
money | a decimal amount and an ISO 4217 code | none | the amount, and the code under <name>.currency | Numbers and money |
boolean | true or false | none | the boolean | Boolean and select |
select | one option, or a list with multiple | none | each value | Boolean and select |
date | a calendar day | none | the day at midnight UTC | Dates and times |
datetime | a wall-clock time, its IANA zone and the UTC instant | none | the instant | Dates and times |
recurrence | a start, duration, zone, repeat rule, extra and removed dates | none | nothing; occurrences are materialised separately | Dates and times |
geo | a latitude, longitude and precision | none | latitude and longitude | Places |
geo_shape | a GeoJSON Polygon or MultiPolygon | none | nothing; the bounding box and centroid are kept for containment queries | Places |
address | a country and its address components | none | country, locality, administrative area, postal code and point, as sub-keys | Places |
phone | an E.164 number with its national form and region | none | the E.164 number | Phone and opening hours |
opening_hours | regular hours, seasons, exceptions and holidays | none | whether any hours are set | Phone and opening hours |
asset | one library asset, or a list with multiple, with per-use framing, alt text and caption | locale | each asset id | Asset |
link | one link, or a list with multiple, to a document, asset, URL, email, phone, site or anchor | locale | nothing; document and asset targets are tracked as references | Link |
video | a YouTube, Vimeo, library or file video with poster, captions, title and transcript | locale | the poster and library asset ids | Video |
seo | a search title and description and their social pair | locale | nothing | SEO |
form | one of the site’s form endpoints, by id | none | the endpoint id | Form |
relation | references to documents, tags, smart lists, assets, organisations or people | none | each target | Relations |
portable_text | rich text as Portable Text | locale | nothing | Blocks and rich text |
repeater | an ordered list of items with the same child fields | locale | children with index: true | Blocks and rich text |
blocks | an ordered list of items, each one of the declared blocks | locale | children with index: true | Blocks and rich text |
There is no file, image, colour, table, duration or daterange field type. Use asset for files and images, and two date or datetime fields with a validation rule for a range.
Field groups
A field group is a named list of fields declared once in config/schema/_shared.yaml and included in any type, repeater or block with - use: <name>:
# config/schema/_shared.yaml
field_groups:
contact:
- { name: email, type: text, format: email }
- { name: phone, type: phone } # config/schema/venue.yaml
key: venue
label: Venue
fields:
- { name: title, type: text, required: true }
- use: contact The group’s fields become fields of the including type, exactly as if declared there. A group name is camelCase. A use: entry declares nothing else (no name, no type). A group may include another group, but not itself. A variant’s fields cannot use a group.
Ids for a group’s fields are written into _shared.yaml by check --fix, and a field id is unique by declaration, so every type that includes the group shares the same field ids.
Errors you may see
| Message | Cause |
|---|---|
field "<name>" has no id | Run engine-dmo check --fix. |
field name "<name>" must be camelCase: a lowercase letter then letters and digits | Rename it. |
field "<name>" is declared twice | Two entries share a name at the same level. |
"<name>" is an engine-managed field and cannot be declared | See Reserved names. |
unknown field type "<type>" | The type is not in the table above; the message lists the known types. |
field type <type> does not accept a parameter "<key>" | A misspelt or unsupported parameter; a close match is suggested. |
field type <type> requires the parameter "<key>" | select needs options, relation needs to. |
field type <type> does not take child fields | fields: or blocks: on a type that has none. |
unique applies to text, slug, number, select, phone and date fields, not <type> | Remove unique. |
warning: a <type> field is rarely translated; translate: <mode> means one value per <mode> | A field whose type defaults to none was given a translate mode; intended only if you really want one value per locale. |
unknown field group "<name>" | No such group in _shared.yaml. |
Content types
Every key a type file takes (key, extends, label, ordering, template, singleton, variants, sites, groups, revisions and the rest), how to extend a core type, and the rules check enforces.
Text and slug
The text field (single or multi-line, length limits, pattern, email format) and the slug field (a per-locale URL segment generated from another field), with parameters, validation and template values.