Control Flow Guide
Updated Mar 28, 2026
DataMagik DocumentsControl Flow Guide
Master conditional logic and loops in your document templates for dynamic content generation.
Table of Contents
- if/else/end - Conditional Rendering
- range/end - Looping
- with/end - Context Setting
- Comparison Operators
- Logical Operators
- Real-World Examples
- Best Practices
1. if/else/end - Conditional Rendering
Basic if Statement
{{if .IsPaid}}
<span class="badge badge-success">PAID</span>
{{end}}if/else Statement
{{if .IsActive}}
<span class="status-active">Active</span>
{{else}}
<span class="status-inactive">Inactive</span>
{{end}}if/else if/else Chain
{{if eq .Status "completed"}}
<span class="badge-success">Completed</span>
{{else if eq .Status "pending"}}
<span class="badge-warning">Pending</span>
{{else}}
<span class="badge-info">Unknown</span>
{{end}}Checking for Empty/Nil Values
{{if .Email}}
<p>Contact: {{.Email}}</p>
{{else}}
<p>No contact email provided</p>
{{end}}Negation with not
{{if not .IsDeleted}}
<div class="active-record"><p>{{.Name}}</p></div>
{{end}}2. range/end - Looping
Simple Array Iteration
<ul>
{{range .Tags}}
<li>{{.}}</li>
{{end}}
</ul>Iterating Objects in Array
<table>
<thead><tr><th>Product</th><th>Price</th><th>Qty</th></tr></thead>
<tbody>
{{range .Products}}
<tr><td>{{.Name}}</td><td>${{.Price}}</td><td>{{.Quantity}}</td></tr>
{{end}}
</tbody>
</table>range with Index
{{range $index, $item := .Items}}
<div>Item #{{$index}}: {{$item.Name}}</div>
{{end}}range with else (Empty Arrays)
{{range .Notifications}}
<li>{{.Message}}</li>
{{else}}
<li>No notifications</li>
{{end}}Nested range Loops
{{range .Categories}}
<div class="category">
<h3>{{.Name}}</h3>
<ul>
{{range .Products}}<li>{{.Name}} - ${{.Price}}</li>{{end}}
</ul>
</div>
{{end}}3. with/end - Context Setting
Basic with Statement
{{with .Customer}}
<div class="customer">
<h2>{{.Name}}</h2>
<p>{{.Email}}</p>
</div>
{{end}}with/else
{{with .BillingAddress}}
<div><p>{{.Street}}</p><p>{{.City}}, {{.State}}</p></div>
{{else}}
<p>No billing address on file</p>
{{end}}Accessing Parent Context
Use $ to access root context inside with or range:
{{with .Order}}
<p>Order: {{.Number}}</p>
<p>Company: {{$.CompanyName}}</p>
{{end}}4. Comparison Operators
| Operator | Description | Example |
|---|---|---|
eq | Equal | {{if eq .Status "active"}} |
ne | Not equal | {{if ne .Status "deleted"}} |
lt | Less than | {{if lt .Stock 10}} |
le | Less than or equal | {{if le .Score 60}} |
gt | Greater than | {{if gt .Price 1000}} |
ge | Greater than or equal | {{if ge .Age 18}} |
Combined Comparisons
{{if and (ge .Price 100) (le .Price 500)}}
<span>Mid-range product</span>
{{end}}
{{if or (eq .Type "urgent") (eq .Type "critical")}}
<span class="alert">High Priority!</span>
{{end}}5. Logical Operators
and - Logical AND
{{if and .IsActive .IsPaid}}
<span>Active & Paid</span>
{{end}}or - Logical OR
{{if or .IsAdmin .IsModerator}}
<button>Edit</button>
{{end}}not - Logical NOT
{{if not .IsDeleted}}
<div>{{.Name}}</div>
{{end}}Complex Conditions
{{if and (not .IsDeleted) (or .IsActive .IsPending)}}
<div class="available">{{.Name}}</div>
{{end}}6. Real-World Examples
Invoice with Conditional Sections
<div class="invoice">
<h1>Invoice #{{.InvoiceNumber}}</h1>
{{if .IsPaid}}
<div class="paid-stamp">PAID on {{.PaidDate | dateFormat "Jan 2, 2006"}}</div>
{{else}}
<div class="unpaid">Due: {{.DueDate | dateFormat "Jan 2, 2006"}}
{{if .IsOverdue}}<span class="overdue">OVERDUE</span>{{end}}
</div>
{{end}}
<table>
{{range .Items}}
<tr>
<td>{{.Description}}</td>
<td>{{.Quantity}}</td>
<td>${{.Price | printf "%.2f"}}</td>
</tr>
{{end}}
</table>
{{if gt .DiscountAmount 0}}<p>Discount: -${{.DiscountAmount | printf "%.2f"}}</p>{{end}}
{{if gt .Tax 0}}<p>Tax: ${{.Tax | printf "%.2f"}}</p>{{end}}
<p class="total">Total: ${{.Total | printf "%.2f"}}</p>
{{with .Notes}}<div class="notes"><h3>Notes</h3><p>{{.}}</p></div>{{end}}
</div>Product Listing with Filters
{{range .Products}}
{{if not .IsDiscontinued}}
<div class="product">
<h3>{{.Name}}</h3>
{{if .OnSale}}
<p><span class="original">${{.OriginalPrice | printf "%.2f"}}</span>
<span class="sale">${{.SalePrice | printf "%.2f"}}</span></p>
{{else}}
<p>${{.Price | printf "%.2f"}}</p>
{{end}}
{{if eq .Stock 0}}<p class="out-of-stock">Out of Stock</p>
{{else if lt .Stock 5}}<p class="low-stock">Only {{.Stock}} left!</p>
{{else}}<p class="in-stock">In Stock</p>{{end}}
</div>
{{end}}
{{else}}
<p>No products available.</p>
{{end}}7. Best Practices
- Keep Logic Simple — Move complex logic to your application, not templates
- Use with for Nested Objects — Makes templates cleaner
- Handle Empty Cases — Always provide
elsebranches - Save Root Context — Use
$root := .when nesting - Use range/else — Handle empty arrays gracefully
- Comment Complex Logic — Use
{{/* comments */}}
Common Patterns
<!-- Show/Hide -->
{{if .ShowSection}}<section>Content</section>{{end}}
<!-- Alternative Content -->
{{if .HasData}}<div>{{.Data}}</div>{{else}}<div>No data</div>{{end}}
<!-- Status Styling -->
<div class="status-{{.Status | lower}}">...</div>