Skip to main content
Version: 0.3.36

Archetypes

An Archetype describes how a node of a given NodeType is edited and rendered. The NodeType says what a node is and which properties it stores. The archetype adds a set of editor fields, an optional layout for those fields, and rules about which Element types may be placed inside the node's content. A node names its archetype in the archetype column, next to node_type.

A single NodeType can have several archetypes. A blog:Article may be edited as a plain post in one place and as a landing page with hero and text blocks in another. The stored data is the same; the archetype changes the editing experience and gives the validator a richer schema to check content against.

What an archetype contains

name: arch:LandingPage
title: Landing Page
base_node_type: blog:Article
fields:
- $type: TextField
name: title
required: true
- $type: TextField
name: subtitle
- $type: SectionField
name: sections
allowed_element_types:
- arch:Hero
- arch:TextBlock
layout:
- type: container
direction: Vertical
children:
- type: field
name: title
- type: field
name: subtitle
width: 50%
- type: field
name: sections
publishable: true
FieldTypeMeaning
namestringIdentifier, conventionally namespace:Name
extendsstringParent archetype whose fields, layout and strict are inherited
base_node_typestringThe NodeType this archetype applies to. A node using the archetype must have exactly this node_type
title, description, iconstringEditor labels
fieldsarray of field schemasEditor fields. Same field schema as element types, tagged with $type
layoutarray of layout nodesHow the fields are arranged in the editor
strictboolWhen true, a node may only carry properties named in the resolved fields
publishableboolSet by publishing. Archetypes can be used by nodes whether or not they are published
initial_contentobjectStored and returned as-is; the server does not apply it when a node is created
metamapFree-form data, stored untouched

The full list of field types (TextField, RichTextField, NumberField, DateField, BooleanField, MediaField, ReferenceField, TagField, OptionsField, LocationField, JsonObjectField, CompositeField, ElementField, SectionField, ListingField) and the layout node types are described on the Elements page. The important one for archetypes is SectionField: a list of element instances restricted to allowed_element_types.

Archetype, NodeType and mixin

ConceptDefinesExample
NodeTypeStorage schema and behaviour: property types, required, unique, indexes, versionable, publishableblog:Article
ArchetypeEditor fields, layout and allowed elements for nodes of one NodeTypearch:LandingPage
MixinA NodeType with is_mixin: true whose properties are merged into other NodeTypesraisin:VirtualNode

Mixins change what a node stores. Archetypes change how it is edited and validated as content. See Using Mixins.

Inheritance

An archetype can extends another. Resolution walks the chain (parent first), merges fields by name with the child's definition winning, takes the nearest layout and the nearest explicit strict. The chain is limited to 20 levels and cycles are rejected.

Ask the server for the merged result rather than merging yourself:

curl -s localhost:8090/api/management/docs-model/main/archetypes/arch:CampaignPage/resolved \
-H "Authorization: Bearer $TOKEN"
{
"archetype": { "name": "arch:CampaignPage", "extends": "arch:LandingPage", "fields": [ ... ], "version": 1 },
"resolved_fields": [
{ "$type": "DateField", "name": "ends_on", "config": { "date_mode": "Date" } },
{ "$type": "SectionField", "name": "sections", "allowed_element_types": ["arch:Hero", "arch:TextBlock"] },
{ "$type": "TextField", "name": "subtitle", "required": true },
{ "$type": "TextField", "name": "title", "required": true }
],
"resolved_layout": [ { "type": "container", "direction": "Vertical", "children": [ ... ] } ],
"inheritance_chain": ["arch:CampaignPage", "arch:LandingPage"],
"resolved_strict": true
}

Here arch:CampaignPage added ends_on, made subtitle required, and inherited sections, title, the layout and strict from arch:LandingPage. resolved_fields is sorted by name.

The JavaScript client exposes the same view as db.archetypes().getResolved(name). Schemas are stored per branch, so db.onBranch('staging') resolves against another branch.

What the server validates

When a node carries an archetype, the write is checked against the resolved archetype in addition to the NodeType rules:

  • base_node_type must equal the node's node_type.
  • Every field with required: true must be present in properties.
  • A SectionField value must be a list of elements whose element_type is in allowed_element_types, and each element is validated against its element type (required fields, strict mode).
  • An ElementField value must be an element of the declared element_type.
  • With strict: true, any property not named in the resolved fields is rejected. The server's own reserved $ properties ($mixins, $supertypes) are exempt, as they are under a strict NodeType.

Examples of the errors, as returned by POST /api/repository/{repo}/{branch}/head/{ws}/:

{"code":"VALIDATION_FAILED","message":"Archetype 'arch:LandingPage' is only valid for node type 'blog:Article', but node '' uses 'blog:Author'"}
{"code":"VALIDATION_FAILED","message":"Element type 'blog:Nope' is not allowed in field 'archetype 'arch:LandingPage'.sections'"}
{"code":"VALIDATION_FAILED","message":"Missing required field 'heading' at archetype 'arch:LandingPage'.sections[0]"}

Field-level settings such as max_length or min_value live in each field's config and are editor hints. The server does not enforce them.

Switching archetypes

Because the archetype is just a column on the node, changing it is an ordinary update. A blog:Article written with arch:LandingPage can be re-saved with arch:CampaignPage; the properties stay where they are and the next write is validated against the new archetype. This is what lets one data model serve different editors and front ends. See DCAD.

Where archetypes live

  • HTTP: /api/management/{repo}/{branch}/archetypes with the same verbs as NodeTypes. Bodies are wrapped as {"archetype": {...}}. See Using Archetypes.
  • Packages: one YAML file per archetype under package/archetypes/, installed with the package.
  • SQL: CREATE ARCHETYPE 'arch:Post' BASE_NODE_TYPE 'blog:Article' TITLE 'Post' FIELDS (heading String REQUIRED) PUBLISHABLE creates the record with its fields, ALTER ARCHETYPE ... ADD FIELD / DROP FIELD / MODIFY FIELD changes them, and DROP ARCHETYPE 'arch:Post' removes it. Two things the DDL grammar cannot say — which element types a SectionField accepts, and ENCRYPTED — still need HTTP or YAML. See DDL.

Next steps

  • Elements for the field and element type reference
  • Using Archetypes for the step-by-step guide
  • NodeTypes for the storage schema an archetype sits on
  • DCAD for the design approach behind archetypes