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