A Global Field (internally: Calculated Field) is a named, reusable value that is computed at the moment a Dynamic Document Template is rendered and injected into the Dynamic Document context. You define the field once — in the UI, using a restricted Python expression — and reference it from the template body as {d.calculated.field_name}.
This eliminates two problems that today force carriers to fork templates or write fragile inline conditional logic:
- Values that don't exist in the raw context — driver age from date-of-birth, totals with tax, conditional labels, normalized strings.
- Wording that has to vary by state, line, or scenario — one template with a calculated
state_labelreplaces several near-duplicate state-specific templates.
When to use a Global Field
Reach for a Global Field whenever:
- You catch yourself maintaining two or more templates that differ only in a state-specific phrase, a label, or a derived value.
You need a value that isn't in the raw
get_deliverable_preview_jsoncontext — e.g. a driver's age from their DOB, a premium with tax, or a "young driver" indicator.
Keep using raw context references ({d.field}) for values that already exist in the JSON and need no transformation.
Concepts
Global vs. template-specific
A Global Field has a scope:
- Global — defined once, applied to every Dynamic Document Template.
- Template-specific — defined on one template, applies only to that template.
At render time both are loaded and merged. If a global field and a template-specific field share a name and path, the template-specific field wins. Use global fields for values that mean the same thing everywhere (e.g. state_label, today_long). Use template-specific fields for one-off computations a single document needs.
The calculated namespace — raw context is never modified
Calculated values are always injected under a calculated namespace. The raw context is never mutated. This protects you from name collisions with existing context fields and makes it obvious in the template what came from data vs. what was computed.
Template references:
| Location | Template syntax |
|---|---|
| Root-level field | {d.calculated.field_name} |
| Field on an array element | {d.drivers[i].calculated.field_name} |
Dependencies and sort order
Calculated fields can reference other calculated fields. Order matters — fields are evaluated in their sort order, so a field that depends on another must come after it. The UI enforces this on save and on reorder.
Newly created fields are appended at the end of the order by default.
How to add a Global Field
- Open the Dynamic Document Template in the template editor.
- Open the Calculated Fields (Global Fields) section in template settings.
- You will see a merged list: global fields (with a global badge) and template-specific fields. Global fields are read-only here — edit them from the global Calculated Fields settings page.
- Click Add Field and supply:
- Field name — the identifier you will use in
{d.calculated.<name>}. Snake_case is conventional. - Path —
(root)for a top-level field, or an array path likedrivers[*]for a field that should be computed per array element. - Expression — a single-line expression that returns a value, or a multi-line block that assigns to
return_value. Syntax details below. - Description — optional human-readable note.
- Field name — the identifier you will use in
- Click Test. The UI evaluates the expression against real context data from a sample policy and shows the result.
- Save.
Expression syntax
Expressions are evaluated by CarboneContextPostProcessingEngine using RestrictedPython — the same engine the BriteCore Rules engine uses. Expressions are parsed into an AST, validated against an allow-list, then evaluated node-by-node. eval() and exec() are never called.
Single-line vs multi-line
A single-line expression returns its value directly:
"California Policy" if state == "CA" else "Standard Policy"
A multi-line expression must assign the result to return_value:
names = []
for driver in context["drivers"]:
names.append(driver["first_name"])
return_value = ", ".join(names)
Variable references
| Reference | Meaning | Example |
|---|---|---|
field_name | Field in the current scope (when path uses [*]) | date_of_birth |
context["field"] | Field at the context root | context["total_premium"] |
_parent["field"] | Parent scope, when inside an array | _parent["policy_number"] |
_index | Current array index (0-based), when inside an array | _index |
What you can use
Allowed:
- Arithmetic —
+,-,*,/,%,** - Comparisons —
==,!=,<,>,<=,>=,in,not in - Booleans —
and,or,not - Conditionals —
x if condition else y, including chainedelse if … else - For loops —
for item in collection: … - Variable assignment —
tax_rate = 1.08 - Native Python — string concat (
+),.join(),.upper(),.lower(),in,len(),str(),int(),float(),round(),abs(),min(),max(), list indexing[], list.append()
Rejected — the AST validator will reject the expression on save:
importstatements- Arbitrary attribute access via dunders (
__class__,__import__, etc.) eval,exec,open,compilelambdawhileloops (unbounded — useforwith a fixed collection instead)- List/dict comprehensions
- Assignment to anything other than a local name
Custom functions
| Function | Example | Description |
|---|---|---|
age_from_date(date) | age_from_date(date_of_birth) → 41 | Years between the date and today. Matches the Rules engine's age_from_date() naming. |
default(value, fallback) | default(middle_name, "N/A") | Returns fallback if value is None or empty; otherwise returns value. |
Safety guards
- For loops only —
whileis rejected at parse time. - Iteration limit — 10,000 iterations per expression.
- Nesting limit — 3 levels of nested control flow.
- Timeout — 1 second per expression.
- Graceful failure — if an expression raises or times out,
nullis injected, a warning is logged, and the render continues. A failed Global Field never breaks a document.
Examples
Example 1 — state-specific label (root-level)
The classic "one template, every state" use case.
- Field name:
state_label - Path:
(root) Expression:
"California Policy" if context["state"] == "CA" \ else "Texas Policy" if context["state"] == "TX" \ else "Standard Policy"- Template usage:
{d.calculated.state_label}
Example 2 — driver age (per-array element)
- Field name:
driver_age - Path:
drivers[*] Expression:
age_from_date(date_of_birth)
- Template usage:
{d.drivers[i].calculated.driver_age}
Each driver gets their own computed age value; nothing is added to the raw drivers array.
Example 3 — youth surcharge flag (root-level, depends on array data)
- Field name:
has_young_driver - Path:
(root) Expression (multi-line):
flag = False for driver in context["drivers"]: if age_from_date(driver["date_of_birth"]) < 25: flag = True return_value = flag- Template usage:
{d.calculated.has_young_driver}(boolean — use in a Dynamic Docs conditional)
Example 4 — adjusted premium (multi-line, depends on calculated boolean)
This field references another calculated field (has_young_driver). It must be ordered after that field in the sort order.
- Field name:
adjusted_premium - Path:
(root) Expression (multi-line):
base = context["base_premium"] if context["calculated"]["has_young_driver"]: return_value = round(base * 1.25, 2) elif len(context["claims"]) > 2: return_value = round(base * 1.10, 2) else: return_value = base- Template usage:
{d.calculated.adjusted_premium}
Example 5 — safe default for nullable values
- Field name:
safe_middle_name - Path:
(root) Expression:
default(context["middle_name"], "")
- Template usage:
{d.calculated.safe_middle_name}— nevernullin the rendered document.
The Test button
Every field has a Test button next to it in the editor. Clicking Test:
- Loads a sample context (you can pick from your recent renders or paste your own JSON).
- Evaluates the expression against that context exactly as it will run at render time.
- Shows you the result, or the validation/runtime error if it fails.
Use Test before saving — once a field is saved, every render of every template that depends on it runs the expression.
Deleting a Global Field
When you attempt to delete a Global Field, the system checks whether any other Global Field references it. If references exist, deletion is blocked and you are shown the list of dependent fields. Remove or reorder the references first.
Deletion of a field that is only referenced inside template bodies (not by other Global Fields) is allowed, with a warning listing the templates that reference it. Those templates will see null for the deleted field at render time.