Variables in Word Templates
What this guide covers
PDF4me Word templates use the var keyword to declare custom variables directly inside the document. Once declared, a variable can be output anywhere downstream, reassigned in loops to build running totals, or set conditionally to drive dynamic messaging - all without touching the JSON data payload. This guide explains the syntax, scope rules, formatting, and practical patterns for every common template scenario.
Core Syntax at a Glance
Define a named variable and assign an initial value:
<<var [total = 0]>>Render the current value anywhere after declaration:
<<[total]:"F2">>Update the variable value at any point later:
<<var [total = total + item.price]>>Declaration and Basic Usage
The var keyword follows this structure:
<<var [Type Name = Value]>>
Type is optional - the engine infers it from the value. Name is the identifier you reference later. Value can be any literal, data field, or expression.
Simple string variable
<<var [companyName = "Acme Corp"]>>
<<var [companyPhone = "+1-555-0123"]>>
Company: <<[companyName]>>
Contact: <<[companyPhone]>>
For questions, please reach <<[companyName]>> at <<[companyPhone]>>.
The variables are declared once and reused wherever consistency matters - change the value in one place to update the entire document.
Variable Reassignment
Reassign a variable at any later point in the template by writing another <<var>> tag with the same name. The new value takes effect from that point forward.
<<var [status = "Pending"]>>
Current Status: <<[status]>>
<<var [status = "Approved"]>>
Updated Status: <<[status]>>
<<var [status = "Completed"]>>
Final Status: <<[status]>>
Output:
Current Status: Pending
Updated Status: Approved
Final Status: Completed
Variables with Calculations
Variables can hold the result of any arithmetic expression, including LINQ aggregates over data-source collections.
Totals and tax calculation
<<var [subtotal = lineItems.Sum(i => i.quantity * i.price)]>>
<<var [taxRate = 0.10]>>
<<var [taxAmount = subtotal * taxRate]>>
<<var [total = subtotal + taxAmount]>>
Subtotal: $<<[subtotal]:"F2">>
Tax (10%): $<<[taxAmount]:"F2">>
Total: $<<[total]:"F2">>
String concatenation
<<var [firstName = "Jane"]>>
<<var [lastName = "Smith"]>>
<<var [fullName = firstName + " " + lastName]>>
Customer: <<[fullName]>>
String manipulation methods
<<var [upperName = customerName.ToUpper()]>>
<<var [initials = firstName.Substring(0,1) + lastName.Substring(0,1)]>>
Customer: <<[upperName]>>
Initials: <<[initials]>>
Variables in Loops
Declare variables before the <<foreach>> tag and reassign them inside the loop body. The engine carries the value across iterations, making it the standard pattern for running totals and line counters.
Running total across line items
<<var [runningTotal = 0.0]>>
<<foreach [item in lineItems]>>
<<var [lineTotal = item.quantity * item.price]>>
<<var [runningTotal = runningTotal + lineTotal]>>
<<[item.description]>> - <<[item.quantity]>> × $<<[item.price]:"F2">> = $<<[lineTotal]:"F2">> (Running: $<<[runningTotal]:"F2">>)
<</foreach>>
Final Total: $<<[runningTotal]:"F2">>
Row counter
<<var [counter = 0]>>
<<foreach [item in items]>>
<<var [counter = counter + 1]>>
<<[counter]>>. <<[item.name]>>
<</foreach>>
Total Items: <<[counter]>>
Conditional Variables
Use the C# ternary operator ? : to branch a variable value based on data from the payload.
Status label
<<var [statusLabel = orderStatus == "Completed" ? "✓ Complete" : "⚠ Pending"]>>
<<var [urgency = daysUntilDue < 7 ? "URGENT" : "Standard"]>>
Priority: <<[urgency]>>
Status: <<[statusLabel]>>
Tiered discount
<<var [subtotal = items.Sum(i => i.price)]>>
<<var [discountRate = subtotal > 1000 ? 0.15 : 0.05]>>
<<var [discountAmount = subtotal * discountRate]>>
<<var [total = subtotal - discountAmount]>>
Subtotal: $<<[subtotal]:"F2">>
Discount (<<[discountRate * 100]:"F0">>%): –$<<[discountAmount]:"F2">>
Total: $<<[total]:"F2">>
Complete Example: Invoice with All Patterns
Full Invoice TemplateCombines declaration, running totals in a loop, conditional discount, and formatted output.
<<var [companyName = "Tech Solutions Inc."]>>
<<var [proposalDate = DateTime.Now]>>
<<var [validUntil = proposalDate.AddDays(30)]>>
Invoice Date: <<[proposalDate]:"MMMM dd, yyyy">>
Valid Until: <<[validUntil]:"MMMM dd, yyyy">>
Line Items:
<<var [subtotal = 0.0]>>
<<foreach [item in lineItems]>>
<<var [lineTotal = item.quantity * item.unitPrice]>>
<<var [subtotal = subtotal + lineTotal]>>
• <<[item.description]>> - <<[item.quantity]>> @ $<<[item.unitPrice]:"F2">> = $<<[lineTotal]:"F2">>
<</foreach>>
<<var [discountRate = subtotal > 5000 ? 0.10 : 0.05]>>
<<var [discountAmount = subtotal * discountRate]>>
<<var [afterDiscount = subtotal - discountAmount]>>
<<var [tax = afterDiscount * 0.08]>>
<<var [grandTotal = afterDiscount + tax]>>
Subtotal: $<<[subtotal]:"F2">>
Discount (<<[discountRate * 100]:"F0">>%): –$<<[discountAmount]:"F2">>
After Discount: $<<[afterDiscount]:"F2">>
Tax (8%): $<<[tax]:"F2">>
Grand Total: $<<[grandTotal]:"F2">>
Prepared by: <<[companyName]>>
Variable Scope Rules
| Declared where | Available |
|---|---|
| Document root (before any loop) | Everywhere in the document after the declaration |
Inside a <<foreach>> block | Within that iteration; persists outside if declared before the loop |
Inside a nested <<foreach>> | Within that nested scope; visible outside only if pre-declared |
Rule of thumb: Declare any variable you need outside a loop before the <<foreach>> tag. Reassigning inside the loop updates the same variable for all subsequent references.
Formatting Output
Append .NET format strings after the variable name in the output tag:
| Format | Tag example | Renders as |
|---|---|---|
| 2 decimal places | <<[total]:"F2">> | 1234.56 |
| Whole number | <<[rate * 100]:"F0">> | 15 |
| Currency | <<[amount]:"C2">> | $1,234.56 |
| Long date | <<[createdDate]:"MMMM dd, yyyy">> | January 15, 2026 |
| Short date | <<[dueDate]:"MM/dd/yyyy">> | 01/15/2026 |
Best Practices
- Declare before use - The engine processes tags top to bottom; a variable referenced before its
<<var>>tag causes an error. - Use descriptive camelCase names -
grandTotal,taxAmount,invoiceDateare easier to maintain thanv1,tmp,x. - Initialize accumulators to 0 or
""before loops - assigning an uninitialized variable in a loop body can produce null-reference errors. - Calculate once, use many times - Store complex LINQ expressions in a variable rather than repeating the expression in every output tag.
- Avoid name collisions - Do not reuse names that conflict with data-source field names; the engine may resolve the reference ambiguously.