Go Template Syntax Guide
Last updated: October 6, 2025
The DataMagik Document Designer uses Go's powerful template syntax for dynamic content generation. This guide covers the fundamentals with extensive examples.
Table of Contents
- Basic Variable Substitution
- Nested Object Access
- Array Access
- Comments
- Whitespace Control
- Pipeline Operations
- Variables in Templates
Basic Variable Substitution
Simple Variables
Access data fields using dot notation with double curly braces:
<h1>{{.Title}}</h1> <p>{{.Description}}</p> <span>{{.Amount}}</span>
Sample Data:
{ "Title": "Monthly Report", "Description": "Sales performance for September", "Amount": 12500.50 }
Output:
<h1>Monthly Report</h1> <p>Sales performance for September</p> <span>12500.50</span>
Multiple Variables in One Line
<p>Hello {{.FirstName}} {{.LastName}}, your balance is ${{.Balance}}</p>
Sample Data:
{ "FirstName": "John", "LastName": "Doe", "Balance": 1250.75 }
Output:
<p>Hello John Doe, your balance is $1250.75</p>
Nested Object Access
Accessing Nested Properties
Use dot notation to access nested object properties:
<h2>{{.Customer.Name}}</h2> <p>Email: {{.Customer.Email}}</p> <p>{{.Customer.Address.Street}}</p> <p>{{.Customer.Address.City}}, {{.Customer.Address.State}} {{.Customer.Address.Zip}}</p>
Sample Data:
{ "Customer": { "Name": "Acme Corporation", "Email": "contact@acme.com", "Address": { "Street": "123 Business Ave", "City": "New York", "State": "NY", "Zip": "10001" } } }
Output:
<h2>Acme Corporation</h2> <p>Email: contact@acme.com</p> <p>123 Business Ave</p> <p>New York, NY 10001</p>
Deep Nesting Example
<div class="order"> <h3>Order {{.Order.Number}}</h3> <p>Shipped to: {{.Order.Shipping.Recipient.Name}}</p> <p>{{.Order.Shipping.Recipient.Address.Line1}}</p> <p>Tracking: {{.Order.Shipping.TrackingNumber}}</p> </div>
Sample Data:
{ "Order": { "Number": "ORD-2025-001", "Shipping": { "Recipient": { "Name": "Jane Smith", "Address": { "Line1": "456 Oak Street" } }, "TrackingNumber": "1Z999AA10123456784" } } }
Array Access
Direct Index Access
Access array elements by index:
<p>First item: {{index .Items 0}}</p> <p>Second item: {{index .Items 1}}</p> <p>Third item: {{index .Items 2}}</p>
Sample Data:
{ "Items": ["Apple", "Banana", "Cherry"]}
Output:
<p>First item: Apple</p> <p>Second item: Banana</p> <p>Third item: Cherry</p>
Accessing Array of Objects
<p>First customer: {{(index .Customers 0).Name}}</p> <p>First customer email: {{(index .Customers 0).Email}}</p>
Sample Data:
{ "Customers": [ { "Name": "Alice Johnson", "Email": "alice@example.com" }, { "Name": "Bob Wilson", "Email": "bob@example.com" } ] }
Output:
<p>First customer: Alice Johnson</p> <p>First customer email: alice@example.com</p>
Comments
Single-Line Comments
Comments are not rendered in the output:
{{/* This is a comment and won't appear in output */}} <p>{{.Message}}</p> {{/* Another comment */}}
Multi-Line Comments
{{/* This is a multi-line comment It can span multiple lines and won't appear in the output*/}} <div>{{.Content}}</div>
Documentation Comments
Use comments to document your template:
{{/* Customer Information Section */}} <div class="customer-info"> {{/* Display customer name and ID */}} <h2>{{.Customer.Name}} (ID: {{.Customer.ID}})</h2> {{/* Contact details */}} <p>Email: {{.Customer.Email}}</p> <p>Phone: {{.Customer.Phone}}</p> </div>
Whitespace Control
Default Behavior
By default, whitespace around template tags is preserved:
<p> {{.Name}}</p>
Output includes newlines and spaces.
Trim Whitespace Before
Use {{- to remove whitespace before the tag:
<p> {{- .Name}}</p>
Trim Whitespace After
Use -}} to remove whitespace after the tag:
<p> {{.Name -}}</p>
Trim Both Sides
Combine both for complete whitespace control:
<ul> {{- range .Items}} <li>{{- .Name -}}</li> {{- end}} </ul>
Sample Data:
{ "Items": [ {"Name": "Item 1"}, {"Name": "Item 2"}, {"Name": "Item 3"} ] }
Output (compact):
<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>
Pipeline Operations
Using Pipes
Chain operations using the pipe operator |:
<p>{{.Name | upper}}</p><p>{{.Description | lower}}</p><p>{{.Title | title}}</p>
Sample Data:
{ "Name": "john doe", "Description": "IMPORTANT MESSAGE", "Title": "hello world"}
Output:
<p>JOHN DOE</p> <p>important message</p> <p>Hello World</p>
Multiple Pipe Operations
Chain multiple operations:
<p>{{.Email | lower | printf "Contact: %s"}}</p>
Pipe with Function Arguments
<p>{{.Price | printf "%.2f"}}</p> <p>{{.Date | dateFormat "January 2, 2006"}}</p>
Sample Data:
{ "Price": 1234.5, "Date": "2025-09-21" }
Output:
<p>1234.50</p> <p>September 21, 2025</p>
Variables in Templates
Declaring Variables
Use $variable := value syntax to create template variables:
{{$total := .Amount}} <p>Amount: ${{$total}}</p> <p>With Tax: ${{$total | printf "%.2f"}}</p>
Variables in Loops
Capture loop values in variables:
{{range $index, $item := .Products}} <div> <p>{{$index}}. {{$item.Name}}</p> <p>Price: ${{$item.Price}}</p> </div> {{end}}
Sample Data:
{ "Products": [ { "Name": "Widget", "Price": 19.99}, { "Name": "Gadget", "Price": 29.99}, { "Name": "Doohickey", "Price": 39.99 } ] }
Output:
<div> <p>0. Widget</p> <p>Price: $19.99</p> </div> <div> <p>1. Gadget</p> <p>Price: $29.99</p> </div> <div> <p>2. Doohickey</p> <p>Price: $39.99</p> </div>
Using Variables for Calculations
{{$subtotal := .Subtotal}} {{$taxRate := .TaxRate}} {{$tax := .Tax}} {{$total := .Total}} <table> <tr><td>Subtotal:</td><td>${{$subtotal}}</td></tr> <tr><td>Tax Rate:</td><td>{{$taxRate}}%</td></tr> <tr><td>Tax:</td><td>${{$tax}}</td></tr> <tr><td>Total:</td><td>${{$total}}</td></tr> </table>
Capturing Context
Save the current context for later use:
{{$root := .}} {{range .Orders}} <div> <p>Order: {{.Number}}</p> <p>Company: {{$root.CompanyName}}</p> \ </div> {{end}}
Sample Data:
{ "CompanyName": "Acme Corp", "Orders": [ { "Number": "ORD-001" }, { "Number": "ORD-002" } ] }
Output:
<div> <p>Order: ORD-001</p> <p>Company: Acme Corp</p> </div> <div> <p>Order: ORD-002</p> <p>Company: Acme Corp</p> </div>
Complete Example: Invoice Template
Here's a comprehensive example combining multiple concepts:
<!DOCTYPE html> <html> <head> <title>Invoice {{.InvoiceNumber}}</title> <style> body { font-family: Arial, sans-serif; } .header { border-bottom: 2px solid #333; padding-bottom: 20px; } .item { border-bottom: 1px solid #ddd; padding: 10px 0; } .total { font-weight: bold; font-size: 1.2em; } </style> </head> <body> {{/* Invoice Header */}} <div class="header"> <h1>{{.Company.Name | upper}}</h1> <p>{{.Company.Address.Street}}</p> <p>{{.Company.Address.City}}, {{.Company.Address.State}} {{.Company.Address.Zip}}</p> </div> {{/* Invoice Details */}} <div class="details"> <h2>Invoice #{{.InvoiceNumber}}</h2> <p>Date: {{.InvoiceDate | dateFormat "January 2, 2006"}}</p> <p>Due: {{.DueDate | dateFormat "January 2, 2006"}}</p> </div> {{/* Customer Information */}} <div class="customer"> <h3>Bill To:</h3> <p>{{.Customer.Name}}</p> <p>{{.Customer.Email}}</p> </div> {{/* Line Items */}} <table> <thead> <tr> <th>Description</th> <th>Qty</th> <th>Price</th> <th>Total</th> </tr> </thead> <tbody> {{- range .Items}} <tr class="item"> <td>{{.Description}}</td> <td>{{.Quantity}}</td> <td>${{.Price | printf "%.2f"}}</td> <td>${{.Total | printf "%.2f"}}</td> </tr> {{- end}} </tbody> </table> {{/* Total */}} <div class="total"> <p>Subtotal: ${{.Subtotal | printf "%.2f"}}</p> <p>Tax ({{.TaxRate}}%): ${{.Tax | printf "%.2f"}}</p> <p>Total: ${{.TotalAmount | printf "%.2f"}}</p> </div> </body> </html>
Sample Data:
{ "Company": { "Name": "My Company Inc.", "Address": { "Street": "123 Main Street", "City": "Anytown", "State": "CA", "Zip": "90210" } }, "InvoiceNumber": "INV-2025-001", "InvoiceDate": "2025-09-21", "DueDate": "2025-10-21", "Customer": { "Name": "Acme Corporation", "Email": "billing@acme.com" }, "Items": [ { "Description": "Web Development Services", "Quantity": 40, "Price": 125.00, "Total": 5000.00 }, { "Description": "Design Services", "Quantity": 20, "Price": 100.00, "Total": 2000.00 } ], "Subtotal": 7000.00, "TaxRate": 8.5, "Tax": 595.00, "TotalAmount": 7595.00 }
Next Steps
- Learn about String Functions for text manipulation
- Explore Date & Time Functions for date formatting
- Master Control Flow for conditional logic and loops