Control Flow Guide

Updated Mar 28, 2026
DataMagik Documents

Control Flow Guide

Master conditional logic and loops in your document templates for dynamic content generation.

Table of Contents

  1. if/else/end - Conditional Rendering
  2. range/end - Looping
  3. with/end - Context Setting
  4. Comparison Operators
  5. Logical Operators
  6. Real-World Examples
  7. 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

OperatorDescriptionExample
eqEqual{{if eq .Status "active"}}
neNot equal{{if ne .Status "deleted"}}
ltLess than{{if lt .Stock 10}}
leLess than or equal{{if le .Score 60}}
gtGreater than{{if gt .Price 1000}}
geGreater 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

  1. Keep Logic Simple — Move complex logic to your application, not templates
  2. Use with for Nested Objects — Makes templates cleaner
  3. Handle Empty Cases — Always provide else branches
  4. Save Root Context — Use $root := . when nesting
  5. Use range/else — Handle empty arrays gracefully
  6. 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>
Was this page helpful?