Boolean Expressions Guide¶
Boolean expressions allow you to evaluate complex logical conditions directly within placeholders. Combine variables with operators to create dynamic, conditional content without using separate {{#if}} blocks.
Table of Contents¶
- Quick Start
- Expression Syntax
- Logical Operators
- Comparison Operators
- Membership, String, and Existence Operators
- Reserved Words and Literal Quoting
- Combining with Format Specifiers
- Advanced Usage
- Best Practices
- Real-World Examples
Quick Start¶
Wrap any boolean expression in parentheses within a placeholder:
Template:
C# Data:
JSON Data:
Output:
Expression Syntax¶
Basic Rules¶
- Expressions must start with
(- This distinguishes them from simple variables - Expressions must end with
)- Properly close the parentheses - Operators are case-insensitive -
and,AND,Andall work - Spaces are optional -
(var1 and var2)equals(var1and var2)
Expression vs. Simple Variable¶
Simple Variable (no evaluation):
Expression (evaluated):
Complex Expression:
Logical Operators¶
AND Operator¶
Returns true only if both operands are true.
Syntax: and
Truth Table:
| Left | Right | Result |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
Template:
C# Data:
JSON Data:
Output:
OR Operator¶
Returns true if at least one operand is true.
Syntax: or
Truth Table:
| Left | Right | Result |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
Template:
C# Data:
var data = new Dictionary<string, object>
{
["HasPermissionA"] = false,
["HasPermissionB"] = true
};
JSON Data:
Output:
NOT Operator¶
Returns the opposite of the operand.
Syntax: not
Truth Table:
| Value | Result |
|---|---|
| true | false |
| false | true |
Template:
C# Data:
JSON Data:
Output:
Comparison Operators¶
Equality (== or =)¶
Checks if two values are equal. Both == and = are supported.
Template:
C# Data:
JSON Data:
Output:
Inequality (!=)¶
Checks if two values are not equal.
Template:
Data:
Output:
Greater Than (>)¶
Checks if left value is greater than right value.
Template:
Data:
Output:
Greater Than or Equal (>=)¶
Checks if left value is greater than or equal to right value.
Template:
Data:
Output:
Less Than (<)¶
Checks if left value is less than right value.
Template:
C# Data:
JSON Data:
Output:
Less Than or Equal (<=)¶
Checks if left value is less than or equal to right value.
Template:
Data:
Output:
Membership, String, and Existence Operators¶
Membership (in)¶
Checks whether a value is a member of a collection. The right side can be a collection variable, a quoted list literal, or a comma-separated string.
Template:
Data:
Output:
Negate with not: {{(not Role in Roles)}}.
String Checks (contains, startswith, endswith)¶
Template:
Data:
Output:
These comparisons are case-sensitive, like = and ==.
Existence (exists, is empty, is not empty)¶
exists checks that a variable is present regardless of its value; is empty / is not empty check whether a value is missing, null, blank, or an empty collection.
Template:
Data:
Output:
Reserved Words and Literal Quoting¶
The operator keywords are reserved words. The following names are always interpreted as operators, never as variable names or bareword text:
Because of this, string literals must be quoted. Write = "empty", not = empty:
If you leave a reserved word unquoted (for example {{(Category = empty)}}), Templify reads empty as the reserved keyword rather than as the literal text empty, and the expression will not evaluate as you intended. Always quote string literals that could collide with a reserved word.
In inline {{(...)}} expressions, both sides of a comparison are resolved as variables-or-literals. In {{(A = B)}}, both A and B are looked up in your data; the comparison succeeds when the two resolved values are equal. Quote a side ({{(A = "B")}}) when you mean the literal text rather than a variable lookup.
Combining with Format Specifiers¶
The real power comes from combining expressions with format specifiers for human-readable output.
Basic Combination¶
Template:
Data:
Output:
Complex Expression with Checkbox¶
Template:
Data:
Output:
Multiple Conditions with Checkmark¶
Template:
C# Data:
JSON Data:
Output:
OR Logic with Format¶
Template:
Data:
Output:
Advanced Usage¶
Nested Expressions¶
Use nested parentheses to control evaluation order.
Template:
C# Data:
JSON Data:
Output:
Evaluation:
1. (var1 or var2) → (true or false) → true
2. (true and var3) → (true and true) → true
Complex Nested Expressions¶
Template:
Data:
Output:
With Nested Properties¶
Template:
C# Data:
var data = new Dictionary<string, object>
{
["User"] = new
{
IsActive = true,
Profile = new
{
IsComplete = false
}
}
};
JSON Data:
Output:
In Loops¶
Use expressions within loop bodies for dynamic row-level logic.
Template:
C# Data:
var data = new Dictionary<string, object>
{
["Employees"] = new[]
{
new { Name = "Alice", IsActive = true, HasCompletedTraining = true },
new { Name = "Bob", IsActive = true, HasCompletedTraining = false },
new { Name = "Carol", IsActive = false, HasCompletedTraining = true }
}
};
JSON Data:
{
"Employees": [
{ "Name": "Alice", "IsActive": true, "HasCompletedTraining": true },
{ "Name": "Bob", "IsActive": true, "HasCompletedTraining": false },
{ "Name": "Carol", "IsActive": false, "HasCompletedTraining": true }
]
}
Output:
Comparing Numbers from Different Sources¶
Template:
Data:
Output:
String Comparisons¶
Template:
Data:
Output:
Best Practices¶
1. Use Expressions for Simple Logic¶
For inline boolean checks, expressions are cleaner than separate conditionals.
Good (concise):
Less Good (verbose):
{{#if IsActive}}
{{#if IsVerified}}
Status: ☑
{{/if}}
{{/if}}
{{#if (not IsActive)}}
Status: ☐
{{/if}}
{{#if (not IsVerified)}}
Status: ☐
{{/if}}
2. Use Conditionals for Complex Content¶
When you need to show/hide entire blocks of content, use {{#if}} instead.
Good:
{{#if IsActive}}
Account Details:
- Name: {{Name}}
- Email: {{Email}}
- Joined: {{JoinDate}}
{{/if}}
Not Recommended:
3. Keep Expressions Readable¶
Break complex logic into multiple lines or use separate variables.
Good:
Less Readable:
Status: {{(((Age >= 18) and (HasLicense or HasPermit)) and (not IsBlacklisted) and (CreditScore > 600)):checkmark}}
Better Approach:
// In your C# code:
var data = new Dictionary<string, object>
{
["Age"] = 25,
["HasLicense"] = true,
["HasPermit"] = false,
["IsBlacklisted"] = false,
["CreditScore"] = 650,
["IsQualified"] = (25 >= 18) && (true || false) && !false && (650 > 600)
};
Template:
4. Use Meaningful Variable Names¶
Clear variable names make expressions self-documenting.
Good:
Less Clear:
5. Consider Evaluation Cost¶
Complex expressions are evaluated every time they're encountered. For frequently used values, pre-calculate in your data.
Efficient:
Template:
Real-World Examples¶
Approval Workflow Document¶
Template:
Approval Request
================
Request Details:
- Submitted by: {{Requester.Name}}
- Amount: ${{Amount}}
- Date: {{SubmittedDate}}
Approval Status:
- Manager Approval: {{(ManagerApproved):checkbox}}
- Director Approval: {{(DirectorApproved):checkbox}}
- CFO Approval Required: {{(Amount > 10000):yesno}}
- CFO Approved: {{(CFOApproved or Amount <= 10000):checkbox}}
Final Status: {{((ManagerApproved and DirectorApproved) and (CFOApproved or Amount <= 10000)):checkmark}}
C# Data:
var data = new Dictionary<string, object>
{
["Requester"] = new { Name = "John Smith" },
["Amount"] = 15000,
["SubmittedDate"] = "2025-01-15",
["ManagerApproved"] = true,
["DirectorApproved"] = true,
["CFOApproved"] = true
};
JSON Data:
{
"Requester": { "Name": "John Smith" },
"Amount": 15000,
"SubmittedDate": "2025-01-15",
"ManagerApproved": true,
"DirectorApproved": true,
"CFOApproved": true
}
Employee Benefits Eligibility¶
Template:
Benefits Eligibility Report
===========================
Employee: {{Employee.Name}}
Hire Date: {{Employee.HireDate}}
Employment Status: {{Employee.Status}}
Eligibility:
- Health Insurance: {{(Employee.Status == "Full-Time" and Employee.TenureMonths >= 1):yesno}}
- 401(k) Match: {{(Employee.Status == "Full-Time" and Employee.TenureMonths >= 6):yesno}}
- Stock Options: {{(Employee.Status == "Full-Time" and Employee.TenureMonths >= 12):yesno}}
- Gym Membership: {{(Employee.Status != "Contractor"):yesno}}
Data:
{
"Employee": {
"Name": "Sarah Johnson",
"HireDate": "2024-08-15",
"Status": "Full-Time",
"TenureMonths": 5
}
}
System Requirements Check¶
Template:
System Requirements Check
=========================
{{#foreach Requirements}}
{{Name}}: {{(IsMet):checkmark}}
{{/foreach}}
Overall Status: {{((CPUMeetsReq and MemoryMeetsReq) and DiskMeetsReq):active}}
Installation Ready: {{(((CPUMeetsReq and MemoryMeetsReq) and DiskMeetsReq) and OSSupported):yesno}}
C# Data:
var data = new Dictionary<string, object>
{
["Requirements"] = new[]
{
new { Name = "CPU: 2GHz or faster", IsMet = true },
new { Name = "RAM: 8GB minimum", IsMet = true },
new { Name = "Disk: 50GB free space", IsMet = false },
new { Name = "OS: Windows 10 or later", IsMet = true }
},
["CPUMeetsReq"] = true,
["MemoryMeetsReq"] = true,
["DiskMeetsReq"] = false,
["OSSupported"] = true
};
JSON Data:
{
"Requirements": [
{ "Name": "CPU: 2GHz or faster", "IsMet": true },
{ "Name": "RAM: 8GB minimum", "IsMet": true },
{ "Name": "Disk: 50GB free space", "IsMet": false },
{ "Name": "OS: Windows 10 or later", "IsMet": true }
],
"CPUMeetsReq": true,
"MemoryMeetsReq": true,
"DiskMeetsReq": false,
"OSSupported": true
}
Project Risk Assessment¶
Template:
Project Risk Assessment
=======================
Project: {{Project.Name}}
Risk Indicators:
- Behind Schedule: {{(Project.DaysOverdue > 0):yesno}}
- Over Budget: {{(Project.SpentPercentage > 100):yesno}}
- Low Team Morale: {{(Project.MoraleScore < 3):yesno}}
- High Complexity: {{(Project.ComplexityScore >= 8):yesno}}
Risk Level:
- Low Risk: {{((Project.DaysOverdue <= 0) and (Project.SpentPercentage <= 100)):checkbox}}
- Medium Risk: {{((Project.DaysOverdue > 0 or Project.SpentPercentage > 100) and Project.MoraleScore >= 3):checkbox}}
- High Risk: {{((Project.DaysOverdue > 5 or Project.SpentPercentage > 120) or Project.MoraleScore < 3):checkbox}}
Data:
{
"Project": {
"Name": "Website Redesign",
"DaysOverdue": 3,
"SpentPercentage": 95,
"MoraleScore": 4,
"ComplexityScore": 7
}
}
Operator Precedence¶
Expressions are evaluated with standard operator precedence:
- Parentheses
()- Highest priority - NOT
not - Comparison
>,>=,<,<=,=,==,!=,in,contains,startswith,endswith - AND
and - OR
or- Lowest priority
and always binds tighter than or. Use parentheses to override the default grouping.
exists, is empty, and is not empty are postfix operators — they attach directly to the variable that precedes them (e.g. Notes is empty), so they behave like a comparison result and combine with and/or the same way.
Examples¶
Expression: var1 or var2 and var3
Evaluation: var1 or (var2 and var3) ← AND binds tighter
Expression: (var1 or var2) and var3
Evaluation: Parentheses force OR first
Expression: not var1 and var2
Evaluation: (not var1) and var2 ← NOT binds tightest
Summary¶
Boolean expressions enable powerful inline logic in your templates:
- ✅ Logical operators:
and,or,not - ✅ Comparison operators:
=,==,!=,>,>=,<,<= - ✅ Membership, string, and existence operators:
in,contains,startswith,endswith,exists,is empty,is not empty - ✅ Nested expressions with parentheses
- ✅ Combine with format specifiers for readable output
- ✅ Works with nested properties and arrays
- ✅ Use in loops and conditionals
- ✅ Same data works with C# Dictionaries or JSON
- ✅ Case-insensitive operators
For more information, see: - Format Specifiers Guide - Format boolean output - API Reference - Complete API documentation - Examples - More code examples - FAQ - Common questions