Template Syntax Basics
This page introduces the small set of syntax rules that make Wordize templates work.
It covers how tags are written, how expressions are evaluated, and how block tags control repeated or conditional content.
Templates combine ordinary document content with reporting tags. A tag is always wrapped in << and >>, and most tags contain a C#-style expression inside square brackets.
Tag Anatomy
The general pattern looks like this:
<<tag_name [expression] -switch #header // comment >>Not every tag uses every part. In practice, you will mostly work with:
<<[expression]>>for output<<foreach [...]>> ... <</foreach>>for repeated content<<if [...]>> ... <<elseif [...]>> ... <<else>> ... <</if>>for conditional content<<var [...]>>for reusable values
In addition to these fundamentals, Wordize also supports specialized tags for dynamic insertion and formatting operations:
- Using Contextual Object Member Access: short member syntax like
<<[FullName]>>inside scoped blocks - Dynamic Insertion Tags:
doc,html,image,link,bookmark - Advanced Tags Reference:
check,item,textColor,backColor,cellMerge,restartNum
Closing tags use the same name prefixed with /:
<<foreach [segment in booking.Segments]>>
...
<</foreach>>Output Values
Use <<[expression]>> when you want to print the result of an expression directly into the document:
Reference: <<[booking.Reference]>>
Total: <<[booking.TotalAmount]:"0.00">> USD
Departure: <<[booking.DepartureDate]:"dd MMM yyyy">>Expected output:
Reference: BK-48291
Total: 1840.50 USD
Departure: 14 Jun 2026Repeat Collections
Use foreach to duplicate a block for each item in a collection:
Travelers
<<foreach [traveler in booking.Travelers]>>- <<[traveler.FullName]>>
<</foreach>>Expected output:
Travelers
- Avery Chen
- Noah PatelInside a foreach block, you can either reference the iteration variable explicitly or use contextual member access:
<<foreach [traveler in booking.Travelers]>>
- <<[traveler.FullName]>>
- <<[FullName]>>
<</foreach>>Both forms address the current item. The shorter form is convenient inside a focused block, but the explicit form is often easier to read in large templates.
Choose Between Alternate Blocks
Use if, elseif, and else when different document fragments should appear for different data states:
<<if [booking.IsRefundable]>>
Refund policy: Changes are allowed before departure.
<<elseif [booking.HasCreditOnly]>>
Refund policy: Credit only.
<<else>>
Refund policy: Non-refundable.
<</if>>Reuse Calculated Values
Variables are useful when an expression is repeated or when the same derived value must appear in several places:
<<var [displayDate = booking.DepartureDate]>>
Departure: <<[displayDate]:"dd MMM yyyy">>
Reminder: arrive before <<[displayDate.AddHours(-2)]:"HH:mm">>Keep Nested Blocks Readable
If the same tag type is nested several levels deep, headers help prevent closing-tag mistakes:
<<foreach [traveler in booking.Travelers] #travelers>>
<<foreach [bag in traveler.Bags] #bags>>
<<[bag.Tag]>>
<</foreach #bags>>
<</foreach #travelers>>Remove Empty Paragraphs Deliberately
After a tag is processed, the tag itself is removed. If that leaves an empty paragraph behind, choose one of these approaches:
- Use
<<!if ...>>or<<!foreach ...>>for selective cleanup - Enable
ReportBuilderOptions.RemoveEmptyParagraphsfor document-wide cleanup
Example:
<<!if [booking.SpecialInstructions != null]>>
Special instructions: <<[booking.SpecialInstructions]>>
<</if>>If SpecialInstructions is null, the whole paragraph can disappear instead of leaving a blank line.