Rules
Four rule kinds turn one template into every valid variant of a document.
A template without rules produces one document shape. Rules are what let a single template cover every legitimate variant — one signatory or four, a company instead of a person, a mortgage clause that only applies when there is a mortgage.
There are four kinds, and they act at different levels.
Conditions
Every rule kind shares the same condition vocabulary.
Prop
Type
Operators:
| Group | Operators |
|---|---|
| Equality | equals, not_equals |
| Substring | contains, not_contains |
| Ordering | greater_than, less_than |
| Presence | is_empty, is_not_empty |
| Group size | body only: gte, lte, eq on object="…" |
Ordering operators apply to number and date fields only. Comparisons trim surrounding whitespace
and ignore case — nothing else is normalized. A condition on a field that is currently hidden or
disabled reads it as empty.
Conditions in a rule combine with a single logicOperator — and (all must match) or or (any) —
which is required whenever there are two or more conditions. There is no nesting; if you need it,
that is usually a sign the template wants splitting. A field or object carries at most one
visibility rule, and a rule may not depend on its own target.
In the template body the same operators are spelled shorter — is, is-not, contains,
not-contains, gt, lt, empty, not-empty, and gte / lte / eq for group sizes — and
everything is explicit: op is required on every <condition>, result on every <when>, and
match="all" or match="any" whenever a <when> has more than one condition. An unknown value
is an error, never ignored.
The path field is the interesting one. It lets a rule branch on something a model extracted
from an uploaded file — "show the non-resident clause when the analysed ID's country is not ES" —
so document structure can follow the contents of an attachment.
Where rules live
Next to what they govern, and nowhere else. A section rule is a <when> child of its
<section>; a static rule is a <when> inside the <case> it pins; field and object rules sit
inline on the field or object in the form schema. There is no separate rules blob — frontmatter
carrying one is rejected on import.
That is deliberate: a rule and the thing it describes used to live in different halves of the file, and the two disagreeing is how a hard-coded price once shipped inside a live document.
All of them are frozen into a template version on publish, so a document's behaviour cannot change under it.
The templates page has a worked example of every rule kind and every operator.