Operators
The expression engine supports arithmetic, comparison, and logical operators.
Arithmetic operators
| Operator | Description | Example | Result |
|---|---|---|---|
+ | Addition / string concatenation | {{price + tax}} | 110 |
- | Subtraction | {{total - discount}} | 90 |
* | Multiplication | {{price * quantity}} | 50 |
/ | Division | {{total / count}} | 25 |
% | Modulo (remainder) | {{index % 2}} | 0 or 1 |
** | Exponentiation | {{base ** 2}} | 9 |
String concatenation with +
When either operand is a string, + performs concatenation:
{{firstName + " " + lastName}} β "Alice Smith"
{{"ID-" + id}} β "ID-42"Comparison operators
| Operator | Description | Example | Result |
|---|---|---|---|
== | Strict equality | {{status == "active"}} | true or false |
=== | Strict equality | {{status === "active"}} | true or false |
!= | Strict inequality | {{type != "admin"}} | true or false |
!== | Strict inequality | {{type !== "admin"}} | true or false |
> | Greater than | {{age > 18}} | true or false |
< | Less than | {{price < 100}} | true or false |
>= | Greater than or equal | {{age >= 21}} | true or false |
<= | Less than or equal | {{score <= 50}} | true or false |
Both == and === use strict equality. There is no loose equality β == behaves identically to ===. Similarly, != and !== both use strict inequality. This is a deliberate safety choice.
String literals in comparisons
When comparing against a string literal on the right side, the literal is treated as a value, not as a field name.
{ "status": "active", "active": true }{{status == "active"}} β true (compares status field to string "active")
{{status == active}} β false (compares "active" to boolean true)This means "active" on the right side of a comparison is always the string "active", even if the data has a field called active. This only applies to comparisons β outside of comparisons, "active" would resolve to the field value.
Logical operators
| Operator | Description | Example | Result |
|---|---|---|---|
&& | Logical AND | {{age >= 18 && status == "active"}} | true if both are true |
|| | Logical OR | {{role == "admin" || role == "owner"}} | true if either is true |
Short-circuit evaluation
Logical operators use short-circuit evaluation:
&&β if the left side is falsy, the right side is not evaluated||β if the left side is truthy, the right side is not evaluated
Operator precedence
From highest to lowest:
**(exponentiation)*,/,%(multiplicative)+,-(additive)>,<,>=,<=(relational)==,===,!=,!==(equality)&&(logical AND)||(logical OR)
Use parentheses to override precedence:
{{(price + tax) * quantity}} β adds first, then multiplies
{{price + tax * quantity}} β multiplies first, then adds