Skip to main content Link Search Menu Expand Document (external link)

Expression Functions

Master built-in functions for string manipulation, math operations, dates, and conditional logic.


Learning Objectives

By the end of this article, you’ll be able to:

  • Use string functions (concat, substring, upper, lower)
  • Perform math operations (add, subtract, multiply, divide)
  • Use the calc() function for calculations
  • Work with date functions
  • Apply conditional functions (if, choose)
  • Combine functions in expressions

Function Syntax

Functions are called within expression brackets:

{{function(arg1, arg2, ...)}}

String Functions

concat() - Concatenate Strings

<!-- Combine multiple strings -->
<p>{{concat(model.firstName, ' ', model.lastName)}}</p>

<!-- Result: John Doe -->

<!-- Combine with literals -->
<p>{{concat('Hello, ', model.name, '!')}}</p>

<!-- Result: Hello, John! -->

upper() - Convert to Uppercase

<p>{{upper(model.name)}}</p>

<!-- Input: john doe -->
<!-- Result: JOHN DOE -->

lower() - Convert to Lowercase

<p>{{lower(model.name)}}</p>

<!-- Input: JOHN DOE -->
<!-- Result: john doe -->

substring() - Extract Part of String

<!-- substring(string, start, length) -->
<p>{{substring(model.description, 0, 50)}}</p>

<!-- Show first 50 characters -->

<!-- substring(string, start) -->
<p>{{substring(model.text, 10)}}</p>

<!-- From position 10 to end -->

trim() - Remove Whitespace

<p>{{trim(model.text)}}</p>

<!-- Input: "  hello  " -->
<!-- Result: "hello" -->

replace() - Replace Text

<!-- replace(string, oldValue, newValue) -->
<p>{{replace(model.text, 'old', 'new')}}</p>

<!-- Input: "This is old text" -->
<!-- Result: "This is new text" -->

Math Functions

add() - Addition

<p>{{add(model.price, model.tax)}}</p>

<!-- price: 100, tax: 8 -->
<!-- Result: 108 -->

<!-- Multiple values -->
<p>{{add(10, 20, 30, 40)}}</p>

<!-- Result: 100 -->

subtract() - Subtraction

<p>{{subtract(model.total, model.discount)}}</p>

<!-- total: 150, discount: 20 -->
<!-- Result: 130 -->

multiply() - Multiplication

<p>{{multiply(model.quantity, model.price)}}</p>

<!-- quantity: 5, price: 20 -->
<!-- Result: 100 -->

divide() - Division

<p>{{divide(model.total, model.count)}}</p>

<!-- total: 100, count: 4 -->
<!-- Result: 25 -->

calc() - Complex Calculations

The calc() function allows complex math expressions:

<!-- Basic arithmetic -->
<p>{{calc(model.price, '+', model.tax)}}</p>

<!-- With literals -->
<p>{{calc(model.quantity, '*', 10)}}</p>

<!-- Multiple operations (evaluated left to right) -->
<p>{{calc(model.price, '*', model.quantity, '+', model.tax)}}</p>

<!-- (price * quantity) + tax -->

<!-- Parentheses for order of operations -->
<p>{{calc('(', model.price, '+', model.tax, ')', '*', model.quantity)}}</p>

<!-- (price + tax) * quantity -->

Supported operators:

  • + Addition
  • - Subtraction
  • * Multiplication
  • / Division
  • ( ) Parentheses for grouping

Example:

doc.Params["model"] = new
{
    price = 100,
    quantity = 3,
    tax = 15
};
<!-- Total with tax -->
<p>Subtotal: {{calc(model.price, '*', model.quantity)}}</p>
<!-- Result: 300 -->

<p>Total: {{calc(model.price, '*', model.quantity, '+', model.tax)}}</p>
<!-- Result: 315 -->

Conditional Functions

if() - Inline Conditional

<!-- if(condition, trueValue, falseValue) -->
<p>{{if(model.isPremium, 'Premium Customer', 'Standard Customer')}}</p>

<!-- Numeric comparison -->
<p>{{if(model.age >= 18, 'Adult', 'Minor')}}</p>

<!-- String comparison -->
<p>{{if(model.status == 'active', 'Active', 'Inactive')}}</p>

choose() - Multiple Conditions

<!-- choose(index, value1, value2, value3, ...) -->
<p>{{choose(model.priority, 'Low', 'Medium', 'High')}}</p>

<!-- If priority is 0: Low -->
<!-- If priority is 1: Medium -->
<!-- If priority is 2: High -->

Comparison Operators

Use in conditional functions:

<!-- Equal -->
{{if(model.status == 'active', 'Yes', 'No')}}

<!-- Not equal -->
{{if(model.status != 'inactive', 'Active', 'Not Active')}}

<!-- Greater than -->
{{if(model.age > 18, 'Adult', 'Minor')}}

<!-- Greater than or equal -->
{{if(model.score >= 70, 'Pass', 'Fail')}}

<!-- Less than -->
{{if(model.temperature < 32, 'Freezing', 'Not Freezing')}}

<!-- Less than or equal -->
{{if(model.grade <= 59, 'Fail', 'Pass')}}

Logical Operators

AND

<!-- Both conditions must be true -->
{{if(model.age >= 18 && model.hasLicense, 'Can Drive', 'Cannot Drive')}}

OR

<!-- At least one condition must be true -->
{{if(model.isAdmin || model.isModerator, 'Has Access', 'No Access')}}

NOT

<!-- Negate condition -->
{{if(!model.isBlocked, 'Active', 'Blocked')}}

Date Functions

now() - Current Date/Time

<p>Generated: {{now()}}</p>

<!-- Result: 2025-01-15 10:30:00 -->

format() - Format Date

<!-- format(date, formatString) -->
<p>{{format(model.orderDate, 'yyyy-MM-dd')}}</p>

<!-- Result: 2025-01-15 -->

<p>{{format(model.orderDate, 'MMMM dd, yyyy')}}</p>

<!-- Result: January 15, 2025 -->

Common format strings:

  • yyyy-MM-dd - 2025-01-15
  • MM/dd/yyyy - 01/15/2025
  • MMMM dd, yyyy - January 15, 2025
  • dd-MMM-yy - 15-Jan-25
  • HH:mm:ss - 14:30:45

Number Formatting

format() - Format Numbers

<!-- Currency -->
<p>{{format(model.amount, 'C')}}</p>

<!-- Result: $1,234.56 -->

<!-- Fixed decimal places -->
<p>{{format(model.price, 'F2')}}</p>

<!-- Result: 123.45 -->

<!-- Percentage -->
<p>{{format(model.rate, 'P')}}</p>

<!-- Result: 12.5% -->

<!-- With thousands separator -->
<p>{{format(model.population, 'N0')}}</p>

<!-- Result: 1,234,567 -->

Practical Examples

Example 1: Invoice Line Total

<table>
    <thead>
        <tr>
            <th>Description</th>
            <th>Qty</th>
            <th>Price</th>
            <th>Total</th>
        </tr>
    </thead>
    <tbody>
        {{#each model.items}}
        <tr>
            <td>{{this.description}}</td>
            <td>{{this.quantity}}</td>
            <td>{{format(this.price, 'C')}}</td>
            <td>{{format(calc(this.quantity, '*', this.price), 'C')}}</td>
        </tr>
        {{/each}}
    </tbody>
</table>

Example 2: Customer Greeting

<h1>{{if(model.timeOfDay < 12, 'Good Morning',
        if(model.timeOfDay < 18, 'Good Afternoon', 'Good Evening'))}},
    {{model.customerName}}!</h1>

Example 3: Status Badge

<div style="padding: 5pt; background-color: {{if(model.status == 'success', '#10b981',
                                                  if(model.status == 'warning', '#f59e0b',
                                                  if(model.status == 'error', '#ef4444', '#6b7280')))}};
             color: white;">
    {{upper(model.status)}}
</div>

Example 4: Discount Calculation

<div class="pricing">
    <p>Original Price: {{format(model.originalPrice, 'C')}}</p>
    <p>Discount ({{model.discountPercent}}%):
       {{format(calc(model.originalPrice, '*', model.discountPercent, '/', 100), 'C')}}</p>
    <p style="font-weight: bold; font-size: 14pt;">
        Final Price: {{format(calc(model.originalPrice, '-',
                                   calc(model.originalPrice, '*', model.discountPercent, '/', 100)), 'C')}}
    </p>
</div>

Example 5: Text Truncation with Ellipsis

<p>
    {{if(length(model.description) > 100,
         concat(substring(model.description, 0, 97), '...'),
         model.description)}}
</p>

Complete Example: Dynamic Report

C# Code:

var doc = Document.ParseDocument("report.html");

doc.Params["model"] = new
{
    reportTitle = "Q4 Sales Report",
    generatedDate = DateTime.Now,
    author = "sales department",
    sales = new[]
    {
        new { region = "North", revenue = 125000, target = 100000 },
        new { region = "South", revenue = 98000, target = 110000 },
        new { region = "East", revenue = 150000, target = 140000 },
        new { region = "West", revenue = 87000, target = 90000 }
    },
    totalRevenue = 460000,
    totalTarget = 440000
};

doc.SaveAsPDF("report.pdf");

Template:

<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
    <title>Sales Report</title>
    <style>
        body {
            font-family: Helvetica, sans-serif;
            margin: 40pt;
        }
        h1 {
            color: #1e40af;
            text-transform: uppercase;
        }
        .header-info {
            font-size: 10pt;
            color: #666;
            margin-bottom: 30pt;
        }
        table {
            width: 100%;
            border-collapse: collapse;
        }
        th {
            background-color: #2563eb;
            color: white;
            padding: 10pt;
            text-align: left;
        }
        td {
            padding: 8pt;
            border-bottom: 1pt solid #e5e7eb;
        }
        .met-target {
            color: #059669;
            font-weight: bold;
        }
        .missed-target {
            color: #dc2626;
        }
    </style>
</head>
<body>
    <h1>{{upper(model.reportTitle)}}</h1>

    <div class="header-info">
        <p>Generated: {{format(model.generatedDate, 'MMMM dd, yyyy HH:mm')}}</p>
        <p>Author: {{concat(upper(substring(model.author, 0, 1)), substring(model.author, 1))}}</p>
    </div>

    <table>
        <thead>
            <tr>
                <th>Region</th>
                <th>Revenue</th>
                <th>Target</th>
                <th>Performance</th>
                <th>Status</th>
            </tr>
        </thead>
        <tbody>
            {{#each model.sales}}
            <tr>
                <td>{{this.region}}</td>
                <td>{{format(this.revenue, 'C0')}}</td>
                <td>{{format(this.target, 'C0')}}</td>
                <td>{{format(calc(this.revenue, '/', this.target), 'P0')}}</td>
                <td class="{{if(this.revenue >= this.target, 'met-target', 'missed-target')}}">
                    {{if(this.revenue >= this.target, '✓ Met', '✗ Missed')}}
                </td>
            </tr>
            {{/each}}
        </tbody>
        <tfoot>
            <tr style="background-color: #eff6ff; font-weight: bold;">
                <td>TOTAL</td>
                <td>{{format(model.totalRevenue, 'C0')}}</td>
                <td>{{format(model.totalTarget, 'C0')}}</td>
                <td>{{format(calc(model.totalRevenue, '/', model.totalTarget), 'P0')}}</td>
                <td class="{{if(model.totalRevenue >= model.totalTarget, 'met-target', 'missed-target')}}">
                    {{if(model.totalRevenue >= model.totalTarget, '✓ Above Target', '✗ Below Target')}}
                </td>
            </tr>
        </tfoot>
    </table>

    <div style="margin-top: 30pt; padding: 15pt; background-color: #fef3c7; border-left: 4pt solid #f59e0b;">
        <strong>Summary:</strong>
        Total revenue of {{format(model.totalRevenue, 'C0')}} is
        {{if(model.totalRevenue >= model.totalTarget,
             concat(format(calc(calc(model.totalRevenue, '-', model.totalTarget), '/', model.totalTarget), 'P0'), ' above target'),
             concat(format(calc(calc(model.totalTarget, '-', model.totalRevenue), '/', model.totalTarget), 'P0'), ' below target'))}}.
    </div>
</body>
</html>

Try It Yourself

Exercise 1: Price Calculator

Create a template that:

  • Shows original price
  • Calculates discount amount
  • Shows final price
  • Uses color coding (green if discounted, black if not)

Exercise 2: Grade Reporter

Create a template that:

  • Shows student name
  • Shows numeric score
  • Calculates letter grade using if() functions
  • Shows “Pass” or “Fail”

Exercise 3: Date Formatter

Create a template that displays the same date in:

  • Short format (MM/dd/yyyy)
  • Long format (MMMM dd, yyyy)
  • ISO format (yyyy-MM-dd)
  • Custom format

Common Pitfalls

❌ Missing Quotes in Strings

{{concat(Hello, model.name)}}  <!-- Error: Hello is not defined -->

Solution: Quote string literals

{{concat('Hello, ', model.name)}}

❌ Wrong calc() Syntax

{{calc(model.price + model.tax)}}  <!-- Error: operators as strings -->

Solution: Operators must be quoted strings

{{calc(model.price, '+', model.tax)}}

❌ Incorrect Parentheses in calc()

{{calc((model.a + model.b), '*', model.c)}}  <!-- Error -->

Solution: Parentheses must be separate arguments

{{calc('(', model.a, '+', model.b, ')', '*', model.c)}}

Next Steps

Now that you can use expression functions:

  1. Template Iteration - Loop through data
  2. Conditional Rendering - Show/hide content
  3. Variables & Params - Store calculated values

Continue learning → Template Iteration