Formulas and Templates
Formulas compute the value of a field automatically. They run when an object is created or updated, and can reference other fields on the same object.
Definition
{
"valueType": "name",
"template": "{{firstName}} {{lastName}}"
}
| Property | Type | Description |
|---|---|---|
valueType | string | The field this formula writes to. |
formula | string | A math/logic expression (shunting-yard syntax). |
template | string | A Handlebars template string. |
templateFile | string | Path to a template file in the repository (relative to root, without extension). |
onlyWhenMissing | boolean | If true, the formula only runs when the target field has no value yet. |
Exactly one of formula, template, or templateFile must be set.
Templates
Templates use Handlebars syntax. They interpolate field values into a string.
{ "valueType": "name", "template": "{{firstName}} {{lastName}}" }
Field names refer to value types on the same object (including inherited ones).
You can embed a formula inside a template using triple braces:
{ "valueType": "summary", "template": "{{jobTitle}} at {{{UPPER(company)}}}" }
Template files are stored in the repository and referenced by path (without extension):
{ "valueType": "description", "templateFile": "templates/contractSummary" }
Math formulas
Math formulas use the shunting-yard expression engine. They support arithmetic, comparisons, logical operators, and a set of built-in functions.
{ "valueType": "fullName", "formula": "CONCAT(firstName, ' ', lastName)" }
{ "valueType": "endDate", "formula": "dateAdd(startDate, 1, 'year')" }
Variables in a formula refer to field names on the same object.
See Formula Functions for the full list of available functions and operators.
onlyWhenMissing
By default, formulas run every time the object is saved, overwriting any manually entered value. Set onlyWhenMissing: true to only compute the value when the field is empty:
{
"valueType": "name",
"template": "{{firstName}} {{lastName}}",
"onlyWhenMissing": true
}
This is useful for fields that have a sensible default but can be overridden manually.
Example: computed display name
The commons.person class uses a template to compute the display name from first and last name:
{
"valueType": "name",
"template": "{{firstName}} {{lastName}}"
}
The commons.employmentAgreement class uses the job title as the display name:
{
"valueType": "name",
"template": "{{jobTitle}}"
}