Who this is for. Content modellers deciding whether a record owns other records, and developers rendering nested records. After this page you can choose between a hierarchy and a relationship, set up either kind of hierarchy, and render a tree without risking runaway recursion.
Two kinds of hierarchy
A record can have a parent record and children. Which records may be its parent depends on its definition, and a definition uses one of two shapes:
| Shape | Set up by | A record's parent must be | Example |
|---|---|---|---|
| Records of one type nesting among themselves | A definition with no parent definition | A record of the same definition, or none | Regions with sub-regions |
| Typed parent and child | A definition that names a parent definition (Defining a custom entity) | A record of exactly that parent definition, always | Tests within an enrolment |
A save enforces the shape. A record of a definition with no parent definition is refused when its parent is a record of another type. A record of a child definition is refused with The parent must be provided when it has no parent, and with The parent belongs to the wrong entity when its parent is of another definition.
What follows the parent
- The site. When the definitions are sited, a child takes its parent's site when the parent is set. Changing the site of an existing record changes it for the record's whole subtree, all the way down.
- The order. When the definition is positioned, records are ordered among the children of one parent (and within one site, when sited), not across the whole definition.
- Not the URL. The detail route is built from a definition's record path alone, with no nesting under the parent's path. Give every child definition a record path of its own: without one, its records have a nested URL that does not resolve.
Adding children in the admin
What the admin offers on a parent record depends on how many child definitions its definition has:
- One child definition: a single + Add <child> action, which creates the child with this record as its parent, such as + Add Test on an enrolment.
- Two or more: a list of create links, one for each child definition the user may create, each with this record as the parent.
- None: neither; records of the definition nest among themselves instead.
A hierarchy or a relationship
Use a hierarchy when the child cannot exist without its parent and is edited from it: a test does not exist without the enrolment it belongs to. Use a relationship when both sides stand on their own and the link, not ownership, is what you model: an enrolment and a course both exist independently, so an enrolment relates to its course (Relationships between records).
Rendering a tree
getChildren() returns a record's children. A nested structure renders with a recursive function in Smarty or a macro in Twig, called with the root record, such as $region on a region's detail page: