Document Layout Patterns
This page explains how reporting tags fit into ordinary document structure.
It focuses on the document elements most teams use in production templates: paragraphs, bulleted or numbered lists, and tables.
The reporting engine does not replace document design. It works inside the content you already place in a DOCX or Markdown-based template, so layout and styling decisions remain part of the template itself.
Paragraph-Based Blocks
Paragraphs are the simplest way to render repeated or conditional content.
Template:
Booking summary
<<foreach [segment in booking.Segments]>>
Flight: <<[segment.Carrier]>> from <<[segment.From]>> to <<[segment.To]>>
<</foreach>>Expected output:
Booking summary
Flight: Pacific Air from Seattle to Tokyo
Flight: Pacific Air from Tokyo to SingaporeThis layout works well for letters, itineraries, summaries, and narrative reports.
Lists
Lists are usually easiest to maintain when one list item maps to one paragraph in the template.
Template:
Travelers
<<foreach [traveler in booking.Travelers]>>
- <<[traveler.FullName]>>
<</foreach>>Expected output:
Travelers
- Avery Chen
- Noah PatelIf your template uses Word list formatting instead of plain text bullets, keep the foreach block inside the list item paragraphs that should repeat.
Tables
Tables are a natural fit for manifests, schedules, and line-item reports. Place the opening and closing foreach tags in the row that should repeat.
Conceptual row template:
| <<foreach [traveler in booking.Travelers]>> <<[traveler.FullName]>> | <<[traveler.Seat ?? "pending"]>> | <<[traveler.MealPreference ?? "standard"]>> | <</foreach>> |Expected result:
| Avery Chen | 12A | vegetarian |
| Noah Patel | pending | standard |For nested data, start with a simple repeating row first and add inner regions only after the base row renders correctly.
Conditional Layout Fragments
Conditional blocks are useful when a paragraph or table row should appear only for certain records.
<<foreach [traveler in booking.Travelers]>>
<<!if [traveler.MealPreference != null]>>
Meal preference: <<[traveler.MealPreference]>>
<</if>>
<</foreach>>The leading ! helps suppress blank paragraphs when the condition is false.
Layout Tips
- Keep the visible text around a tag meaningful even before the report is generated
- Use one repeating region per paragraph or row when possible
- Add nested regions gradually and test after each step
- Move large calculations out of the template and into the bound model