Template builder
What this page is — the tab where a type's wording is written, as a tree of eight kinds of block with the type's fields merged in, beside a live preview.
What it is for — so legal wording is written once, by someone qualified, and every document of the type reproduces it exactly with only the values changing.
The problem it solves — legal wording is copied and edited per document, so no two agreements of the same kind say quite the same thing.
Route: /org/papers/designer/<type> → Template · Permission:
Create/edit/retire project types and template versions..
1. What it is
A template is a stack of blocks. Sections and Conditionals contain their own blocks.
| Block | Renders | Use for |
|---|---|---|
| Section | A titled container | The numbered clauses of an agreement |
| Rich Text | Formatted text with {{field}} tokens | Paragraphs of wording |
| Dynamic Field | One field value, with a format and optional label | "Effective date: 01 Aug 2026" |
| Table | Repeating rows from a Line Items field, with an optional totals footer | Quotations, invoices, salary components |
| Clause | The approved text of a library clause | Standard wording shared between types |
| Page Break | A new PDF page | Before annexures or signatures |
| Conditional | Its children, only when a condition passes | Clauses that apply only sometimes |
| Signature Anchor | Where a signature field is placed | Every signing ceremony |
Two renders exist, and they are not the same thing:
| Preview (this tab) | Document render | |
|---|---|---|
| Where | In your browser | On the server |
| Values | Samples — «Field Label», 42, 1,250.00 | The document's real values |
| Purpose | Shape and layout while building | What authors, recipients and signers see |
2. Why you would use it
- Clauses cannot be broken by authors. They change answers, never prose.
- One clause improvement updates every template. A Clause block renders the library's current approved version, so approving better wording updates every template that inserts it.
- Conditional blocks replace template variants. One type with a conditional non-solicitation section replaces two near-identical types.
- Signature placement is solved once. Signing ceremonies place fields only at anchors — no one drags signature boxes onto a PDF per document.
- Tables do the arithmetic. Line items, tax and totals are computed at render, not typed.
3. How a template renders
- The server walks the block tree for the document's type version.
- Every
{{name}}token is replaced by the document's value for that field, HTML-escaped. - A token naming no field, or a field with no value, becomes an empty string. There is never an error.
- Clause blocks insert the clause's current approved body. A clause with no approved version renders nothing.
- Conditionals are evaluated against the document's values.
- Tables compute line totals, and tax per the type's tax mode.
- Letterhead is applied; Watermark drafts adds a DRAFT overlay to live renders of unapproved documents.
- At finalize, the result is sealed into a PDF with seal, footer and verification code.
Because a missing value renders as nothing, a typo in a token — {{efective_date}} — ships a document
reading "This agreement is made on , between…". Read the preview with real values before publishing, by
creating a test document.
4. Step by step
- Add block → pick a kind. Inside a Section or Conditional, use its own Add.
- In Rich Text, write the wording and insert fields — the available tokens are listed under the editor.
- Drag the ⋮⋮ handle to reorder; the chevron folds a block; the bin deletes it and everything inside it.
- Check the preview on the right.
- Set Page setup for size and margins.
- Save draft, then Publish.
5. Field reference
| Block | Settings | Warnings shown |
|---|---|---|
| Section | Title | — |
| Rich Text | Formatted body, dictation mic, read aloud | — |
| Dynamic Field | Bound field; format, e.g. DD MMM YYYY; optional inline label | — |
| Table | Bound Line Items field; columns (header, field key, optional width); Show totals footer | A note when no Line Items field exists — add one on the Fields tab |
| Clause | Library clause; Locked (do-not-alter rendering) | Notes when the library is empty, or the clause has no approved version |
| Page Break | — | — |
| Conditional | Condition on field values, ALL / ANY groups | — |
| Signature Anchor | Party role: signer, counterparty_signer, approver, owner · Field type: signature, initials, stamp, date | — |
Locked on a Clause block marks it do-not-alter: a counterparty suggestion touching it counts as a material change and re-triggers approval on the document.
Empty template — "No blocks yet". Documents of the type render blank, which is also why a document's preview is empty.
6. Worked example
A finance operations lead builds a Quotation template.
| # | Block | Content |
|---|---|---|
| 1 | Section Quotation | Rich Text: "Quotation {{quote_number_ref}} for {{customer_name}}, valid for {{validity_days}} days." |
| 2 | Table | Bound to items; columns Description / Qty / Rate / Amount; totals footer on |
| 3 | Conditional | When includes_installation eq Yes → Rich Text on installation terms |
| 4 | Clause | Limitation of Liability — Locked |
| 5 | Page Break | — |
| 6 | Signature Anchor ×2 | signer / signature, and counterparty_signer / signature |
The preview shows a table of sample rows totalling 1,250.00, the installation section (sample values satisfy the condition), and an empty space where the clause belongs — the yellow note explains that Limitation of Liability is still pending approval. Legal approves it; the preview fills.
A test document with three real lines and tax mode exclusive renders subtotal, GST and total. The lead
spots "Quotation for Acme" — quote_number_ref is not a field — and replaces it with a Dynamic Field.
7. The admin contract
| Must be true | Where | What breaks without it |
|---|---|---|
| Every token names a field, in lowercase | Fields | Silent blanks |
| A Line Items field exists for each Table | Fields | The table has nothing to render |
| Inserted clauses have an approved version | Clause library | The clause renders empty |
| Signature anchors exist, if the type is signed | This tab | Signing has nowhere to place fields |
| Tax categories exist, if tax mode is on | Finance settings | Tax is not computed |
| A default letterhead exists | Branding | Documents render without one |
8. Downstream
| When you… | Then |
|---|---|
| Publish a template change | New documents use it. Existing documents keep their version's template |
| Approve a new version of an inserted clause | Every unsealed document using the clause renders the new text at once; sealed PDFs do not change |
| Delete a block | Gone from the next published version only |
| Mark a Clause block Locked | Counterparty edits to it re-trigger approval |
9. Don't confuse this with…
| Filling in the fields | Changes one document's values. This changes wording for all future documents |
| Clause library | Shared wording. A Clause block inserts it |
| Branding | Letterhead and seal wrap the template; they are not blocks |
| Drafting AI | Suggests wording to paste. The template is the approved wording |
10. Troubleshooting
| Symptom | Cause |
|---|---|
| A blank where a value belongs | Token typo, a name with capitals, or an empty field (§3) |
| A clause renders empty | It has no approved version |
| The preview looks right but a real document does not | The preview uses samples — create a test document |
| An existing document did not pick up a fix | It keeps its version's template |
| A clause changed on documents nobody edited | A new clause version was approved (§8) |
| Signing cannot place a field | No Signature Anchor for that party role |
| A table is empty | No Line Items field, or the binding points at the wrong one |