Fields that travel together — declared once, nested, judged where they live.
Fields that travel together: an address is a street, a city and a
postcode, and the group is what makes it ONE thing — assigned together,
stored together, read together. The composite kinds (Repeater
is the other) are how structure stays in the model instead of
leaking into prose.
An object keyed by the children:
{ "venue": { "city": "Atlanta", "street": "1234 Edgewood Ave" } }
A group may instead declare flatten, storing its children at the top
level of page data — the group remains an authoring and reuse unit
while the values live flat. Templates read whichever shape the field
declared; the boundary follows the same resolution.
Children are assignments, same as a content type's own fields:
inline definitions, or references to registry fields — so address
is declared once and every type that needs one agrees on what an
address is. Groups nest (a contact holding an address), and a
group may reference itself (recursiveRef) to a declared depth —
the org-chart shape — capped at 16 levels.
| Label | Venue |
| Key | venue |
| Kind | group |
| Children | city (text) · street (text) — inline or registry refs |
Every child is judged where it lives, by the same modules and rules as
a top-level field — venue.city over its max_length reports at
data.venue.city. Conditions gate at every level:
a child hidden by its condition keeps its stored value but does not
judge, so required on a hidden field can never block a save the
editor showed no control for.
<p><%= venue.street %>, <%= venue.city %></p>
The group wakes as an object; children read off it by key.
venue_city alone is just a text
field; a group of one is ceremony.