Control Flow Guide
Last updated: October 6, 2025
Control 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
if/else/end - Conditional Rendering
Basic if Statement
Render content only when a condition is true:
{{if .IsPaid}}
<span class="badge badge-success">PAID</span>
{{end}}
Sample Data:
{
"IsPaid": true
}
Output:
<span class="badge badge-success">PAID</span>
if/else Statement
Choose between two alternatives:
{{if .IsActive}}
<span class="status-active">Active</span>
{{else}}
<span class="status-inactive">Inactive</span>
{{end}}
Sample Data:
{
"IsActive": false
}
Output:
<span class="status-inactive">Inactive</span>
if/else if/else Chain
Multiple conditions:
{{if eq .Status "completed"}}
<span class="badge-success">✓ Completed</span>
{{else if eq .Status "pending"}}
<span class="badge-warning">⏱ Pending</span>
{{else if eq .Status "cancelled"}}
<span class="badge-danger">✗ Cancelled</span>
{{else}}
<span class="badge-info">• Unknown</span>
{{end}}
Sample Data:
{
"Status": "pending"
}
Output:
<span class="badge-warning">⏱ Pending</span>
Checking for Empty/Nil Values
{{if .Email}}
<p>Contact: {{.Email}}</p>
{{else}}
<p>No contact email provided</p>
{{end}}
{{if .Items}}
<p>{{len .Items}} items in cart</p>
{{else}}
<p>Cart is empty</p>
{{end}}
Negation with not
{{if not .IsDeleted}}
<div class="active-record">
<p>{{.Name}}</p>
</div>
{{end}}
range/end - Looping
Simple Array Iteration
Loop through array elements:
<ul>
{{range .Tags}}
<li>{{.}}</li>
{{end}}
</ul>
Sample Data:
{
"Tags": ["urgent", "important", "review"]
}
Output:
<ul> <li>urgent</li> <li>important</li> <li>review</li> </ul>
Iterating Objects in Array
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
{{range .Products}}
<tr>
<td>{{.Name}}</td>
<td>${{.Price}}</td>
<td>{{.Quantity}}</td>
</tr>
{{end}}
</tbody>
</table>
Sample Data:
{
"Products": [
{"Name": "Widget", "Price": 19.99, "Quantity": 5},
{"Name": "Gadget", "Price": 29.99, "Quantity": 3}
]
}
range with Index
Capture both index and value:
{{range $index, $item := .Items}}
<div class="item-{{$index}}">
<p>Item #{{$index}}: {{$item.Name}}</p>
</div>
{{end}}
Sample Data:
{
"Items": [
{"Name": "First Item"},
{"Name": "Second Item"}
]
}
Output:
<div class="item-0"> <p>Item #0: First Item</p> </div> <div class="item-1"> <p>Item #1: Second Item</p> </div>
range with else
Handle empty arrays:
<ul>
{{range .Notifications}}
<li>{{.Message}}</li>
{{else}}
<li>No notifications</li>
{{end}}
</ul>
Sample Data (empty):
{
"Notifications": []
}
Output:
<ul> <li>No notifications</li> </ul>
Nested range Loops
{{range .Categories}}
<div class="category">
<h3>{{.Name}}</h3>
<ul>
{{range .Products}}
<li>{{.Name}} - ${{.Price}}</li>
{{end}}
</ul>
</div>
{{end}}
Sample Data:
{
"Categories": [
{
"Name": "Electronics",
"Products": [
{"Name": "Laptop", "Price": 999},
{"Name": "Mouse", "Price": 25}
]
},
{
"Name": "Books",
"Products": [
{"Name": "Go Programming", "Price": 45}
]
}
]
}
with/end - Context Setting
Basic with Statement
Set context for nested object access:
{{with .Customer}}
<div class="customer">
<h2>{{.Name}}</h2>
<p>{{.Email}}</p>
<p>{{.Phone}}</p>
</div>
{{end}}
Sample Data:
{
"Customer": {
"Name": "John Doe",
"Email": "john@example.com",
"Phone": "+1-555-1234"
}
}
Output:
<div class="customer"> <h2>John Doe</h2> <p>john@example.com</p> <p>+1-555-1234</p> </div>
with/else
Handle missing nested objects:
{{with .BillingAddress}}
<div class="billing">
<p>{{.Street}}</p>
<p>{{.City}}, {{.State}}</p>
</div>
{{else}}
<p>No billing address on file</p>
{{end}}
Accessing Parent Context in with
Use $ to access root context:
{{with .Order}}
<div class="order">
<p>Order: {{.Number}}</p>
<p>Company: {{$.CompanyName}}</p>
<p>Customer: {{.CustomerName}}</p>
</div>
{{end}}
Sample Data:
{
"CompanyName": "Acme Corp",
"Order": {
"Number": "ORD-001",
"CustomerName": "John Doe"
}
}
Output:
<div class="order"> <p>Order: ORD-001</p> <p>Company: Acme Corp</p> <p>Customer: John Doe</p> </div>
Comparison Operators
eq - Equal
{{if eq .Status "active"}}
<span class="active">Active</span>
{{end}}
{{if eq .Count 0}}
<p>No items</p>
{{end}}
ne - Not Equal
{{if ne .Status "deleted"}}
<div class="record">{{.Name}}</div>
{{end}}
lt - Less Than
{{if lt .Stock 10}}
<span class="low-stock">Low Stock!</span>
{{end}}
le - Less Than or Equal
{{if le .Score 60}}
<span class="fail">Failed</span>
{{end}}
gt - Greater Than
{{if gt .Price 1000}}
<span class="premium">Premium Item</span>
{{end}}
ge - Greater Than or Equal
{{if ge .Age 18}}
<p>Adult</p>
{{end}}
Comparison Examples
<!-- Multiple comparisons -->
{{if and (ge .Price 100) (le .Price 500)}}
<span class="mid-range">Mid-range product</span>
{{end}}
{{if or (eq .Type "urgent") (eq .Type "critical")}}
<span class="alert">High Priority!</span>
{{end}}
Logical Operators
and - Logical AND
All conditions must be true:
{{if and .IsActive .IsPaid}}
<span class="status-good">Active & Paid</span>
{{end}}
{{if and (gt .Stock 0) (le .Stock 10)}}
<span class="low-stock">Running low</span>
{{end}}
or - Logical OR
At least one condition must be true:
{{if or .IsAdmin .IsModerator}}
<button>Edit</button>
{{end}}
{{if or (eq .Status "pending") (eq .Status "processing")}}
<span class="in-progress">In Progress</span>
{{end}}
not - Logical NOT
Negate a condition:
{{if not .IsDeleted}}
<div class="active-item">{{.Name}}</div>
{{end}}
{{if not (eq .Status "archived")}}
<button>Archive</button>
{{end}}
Complex Conditions
{{if and (not .IsDeleted) (or .IsActive .IsPending)}}
<div class="available-item">
<p>{{.Name}}</p>
</div>
{{end}}
Real-World Examples
Example 1: Invoice with Conditional Sections
<div class="invoice">
<h1>Invoice #{{.InvoiceNumber}}</h1>
<!-- Payment status -->
{{if .IsPaid}}
<div class="paid-stamp">
<p>PAID</p>
<p>Paid on: {{.PaidDate | dateFormat "Jan 2, 2006"}}</p>
</div>
{{else}}
<div class="unpaid-notice">
<p>Payment Due: {{.DueDate | dateFormat "Jan 2, 2006"}}</p>
{{if .IsOverdue}}
<p class="overdue">OVERDUE</p>
{{end}}
</div>
{{end}}
<!-- Line items -->
<table>
{{range .Items}}
<tr>
<td>{{.Description}}</td>
<td>{{.Quantity}}</td>
<td>${{.Price | printf "%.2f"}}</td>
<td>${{.Total | printf "%.2f"}}</td>
{{if .IsDiscounted}}
<td class="discount">-{{.DiscountPercent}}%</td>
{{end}}
</tr>
{{end}}
</table>
<!-- Totals -->
<div class="totals">
<p>Subtotal: ${{.Subtotal | printf "%.2f"}}</p>
{{if gt .DiscountAmount 0}}
<p>Discount: -${{.DiscountAmount | printf "%.2f"}}</p>
{{end}}
{{if gt .Tax 0}}
<p>Tax ({{.TaxRate}}%): ${{.Tax | printf "%.2f"}}</p>
{{end}}
<p class="total">Total: ${{.Total | printf "%.2f"}}</p>
</div>
<!-- Notes -->
{{with .Notes}}
<div class="notes">
<h3>Notes</h3>
<p>{{.}}</p>
</div>
{{end}}
</div>
Example 2: Order Status Tracker
<div class="order-tracker">
<h2>Order #{{.OrderNumber}}</h2>
<div class="status-timeline">
<!-- Order Placed -->
<div class="step {{if .OrderPlaced}}completed{{end}}">
<span class="icon">✓</span>
<p>Order Placed</p>
{{if .OrderPlaced}}
<p class="date">{{.PlacedDate | dateFormat "Jan 2, 3:04 PM"}}</p>
{{end}}
</div>
<!-- Processing -->
<div class="step {{if .IsProcessing}}active{{else if .Processed}}completed{{end}}">
<span class="icon">{{if .Processed}}✓{{else}}⏱{{end}}</span>
<p>Processing</p>
{{if .Processed}}
<p class="date">{{.ProcessedDate | dateFormat "Jan 2, 3:04 PM"}}</p>
{{end}}
</div>
<!-- Shipped -->
<div class="step {{if .IsShipping}}active{{else if .Shipped}}completed{{end}}">
<span class="icon">{{if .Shipped}}✓{{else}}📦{{end}}</span>
<p>Shipped</p>
{{if .Shipped}}
<p class="date">{{.ShippedDate | dateFormat "Jan 2, 3:04 PM"}}</p>
<p class="tracking">Tracking: {{.TrackingNumber}}</p>
{{end}}
</div>
<!-- Delivered -->
<div class="step {{if .Delivered}}completed{{end}}">
<span class="icon">{{if .Delivered}}✓{{else}}🏠{{end}}</span>
<p>Delivered</p>
{{if .Delivered}}
<p class="date">{{.DeliveredDate | dateFormat "Jan 2, 3:04 PM"}}</p>
{{end}}
</div>
</div>
<!-- Cancellation notice -->
{{if .IsCancelled}}
<div class="cancelled-notice">
<p>This order was cancelled on {{.CancelledDate | dateFormat "Jan 2, 2006"}}</p>
{{with .CancellationReason}}
<p>Reason: {{.}}</p>
{{end}}
</div>
{{end}}
</div>
Example 3: Product Listing with Filters
<div class="product-listing">
<h1>{{.CategoryName}}</h1>
{{range .Products}}
{{if not .IsDiscontinued}}
<div class="product">
<h3>{{.Name}}</h3>
<!-- Price display -->
{{if .OnSale}}
<p class="price">
<span class="original">${{.OriginalPrice | printf "%.2f"}}</span>
<span class="sale">${{.SalePrice | printf "%.2f"}}</span>
<span class="savings">Save {{.SavingsPercent}}%</span>
</p>
{{else}}
<p class="price">${{.Price | printf "%.2f"}}</p>
{{end}}
<!-- Stock status -->
{{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 if le .Stock 20}}
<p class="limited-stock">{{.Stock}} available</p>
{{else}}
<p class="in-stock">In Stock</p>
{{end}}
<!-- Features -->
{{if .Features}}
<ul class="features">
{{range .Features}}
<li>{{.}}</li>
{{end}}
</ul>
{{end}}
<!-- Ratings -->
{{if and .Rating (gt .Rating 0)}}
<div class="rating">
<span class="stars">{{.Rating}} ★</span>
{{if .ReviewCount}}
<span class="reviews">({{.ReviewCount}} reviews)</span>
{{end}}
</div>
{{end}}
<!-- Badges -->
<div class="badges">
{{if .IsNew}}
<span class="badge-new">NEW</span>
{{end}}
{{if .IsBestseller}}
<span class="badge-bestseller">BESTSELLER</span>
{{end}}
{{if .IsFeatured}}
<span class="badge-featured">FEATURED</span>
{{end}}
</div>
</div>
{{end}}
{{else}}
<p class="no-products">No products available in this category.</p>
{{end}}
</div>
Example 4: Conditional Report Sections
<div class="report">
<h1>{{.ReportTitle}}</h1>
<p class="period">Period: {{.StartDate | dateFormat "Jan 2"}} - {{.EndDate | dateFormat "Jan 2, 2006"}}</p>
<!-- Executive Summary (always shown) -->
<section class="summary">
<h2>Executive Summary</h2>
<p>{{.Summary}}</p>
</section>
<!-- Sales Data (only if available) -->
{{with .SalesData}}
<section class="sales">
<h2>Sales Performance</h2>
<p>Total Revenue: ${{.TotalRevenue | printf "%.2f"}}</p>
{{if gt .GrowthRate 0}}
<p class="positive">Growth: +{{.GrowthRate}}%</p>
{{else if lt .GrowthRate 0}}
<p class="negative">Decline: {{.GrowthRate}}%</p>
{{else}}
<p>No change from previous period</p>
{{end}}
{{if .TopProducts}}
<h3>Top Products</h3>
<ol>
{{range .TopProducts}}
<li>{{.Name}} - ${{.Revenue | printf "%.2f"}}</li>
{{end}}
</ol>
{{end}}
</section>
{{end}}
<!-- Customer Data (only if requested) -->
{{if .IncludeCustomerData}}
{{with .CustomerData}}
<section class="customers">
<h2>Customer Insights</h2>
<p>New Customers: {{.NewCustomers}}</p>
<p>Returning Customers: {{.ReturningCustomers}}</p>
{{if .ChurnRate}}
{{if gt .ChurnRate 10}}
<p class="warning">High churn rate: {{.ChurnRate}}%</p>
{{else}}
<p>Churn rate: {{.ChurnRate}}%</p>
{{end}}
{{end}}
</section>
{{end}}
{{end}}
<!-- Recommendations (conditional) -->
{{if and .Recommendations (gt (len .Recommendations) 0)}}
<section class="recommendations">
<h2>Recommendations</h2>
<ul>
{{range .Recommendations}}
<li class="priority-{{.Priority}}">{{.Text}}</li>
{{end}}
</ul>
</section>
{{end}}
</div>
Best Practices
- Keep Logic Simple: Move complex logic to your application, not templates
- Use with for Nested Objects: Makes templates cleaner and easier to read
- Handle Empty Cases: Always provide
elsebranches for better user experience - Save Root Context: Use
$root := .when nesting to access parent data - Validate Data: Check for nil/empty before accessing nested properties
- Use range/else: Handle empty arrays gracefully
- Comment Complex Logic: Use
{{/* comments */}}to explain conditions
Common Patterns
Pattern 1: Show/Hide Sections
{{if .ShowSection}}
<section>Content here</section>
{{end}}
Pattern 2: Alternative Content
{{if .HasData}}
<div>{{.Data}}</div>
{{else}}
<div>No data available</div>
{{end}}
Pattern 3: Status-Based Styling
<div class="item status-{{.Status | lower}}">
{{if eq .Status "active"}}
<!-- Active content -->
{{else}}
<!-- Inactive content -->
{{end}}
</div>
Pattern 4: Conditional Formatting
{{if gt .Amount 1000}}
<span class="high-value">${{.Amount}}</span>
{{else}}
<span>${{.Amount}}</span>
{{end}}
Next Steps
- Explore Barcode Generation
- Learn about Chart Generation
- Check out Starter Templates
Pro Tip: Test all conditional branches with different sample data to ensure your template handles all cases correctly!