Basic Syntax
| Syntax | Description | Example |
|---|
{{.}} | The current value context | Hello, {{.}}! |
{{.Field}} | Access struct field or map key | Name: {{.Name}} |
{{.Method}} | Call a method on context | Age: {{.GetAge}} |
{{/* comment */}} | Comment (not rendered) | {{/* This is a comment */}} |
{{- .}} | Trim whitespace before | {{- .Name}} (remove whitespace before) |
{{.}} -}} | Trim whitespace after | {{.Name -}} (remove whitespace after) |
Variables
| Syntax | Description | Example |
|---|
{{$name := value}} | Define a variable | {{$name := "John"}} |
{{$name}} | Use a variable | Hello, {{$name}}! |
{{$variable := .Field}} | Store field in variable | {{$email := .Email}} |
{{with $x := .Field}}...{{end}} | Define and with | {{with $user := .User}}{{$user.Name}}{{end}} |
Control Structures
Conditionals
| Syntax | Description | Example |
|---|
{{if .Condition}}...{{end}} | Simple if | {{if .LoggedIn}}Welcome!{{end}} |
{{if .Condition}}...{{else}}...{{end}} | If/else | {{if .LoggedIn}}Welcome!{{else}}Please login{{end}} |
{{if .Cond1}}...{{else if .Cond2}}...{{else}}...{{end}} | If/else if/else | {{if .IsAdmin}}Admin{{else if .IsMember}}Member{{else}}Guest{{end}} |
Loops
| Syntax | Description | Example |
|---|
{{range .Items}}...{{end}} | Loop over array/slice/map | {{range .Users}}{{.Name}}{{end}} |
{{range $index, $element := .Items}}...{{end}} | Loop with index | {{range $i, $user := .Users}}{{$i}}: {{$user.Name}}{{end}} |
{{range $key, $value := .Map}}...{{end}} | Loop over map | {{range $k, $v := .Data}}{{$k}}: {{$v}}{{end}} |
{{range .Items}}...{{else}}...{{end}} | Range with empty case | {{range .Users}}{{.Name}}{{else}}No users found{{end}} |
Context Control
| Syntax | Description | Example |
|---|
{{with .Field}}...{{end}} | Changes dot | {{with .User}}Name: {{.Name}}{{end}} |
{{with .Field}}...{{else}}...{{end}} | With/else | {{with .User}}Name: {{.Name}}{{else}}No user found{{end}} |
Template Composition
| Syntax | Description | Example |
|---|
{{define "name"}}...{{end}} | Define a named template | {{define "header"}}...{{end}} |
{{template "name" .}} | Include template with current context | {{template "header" .}} |
{{template "name" .Field}} | Include template with different context | {{template "userInfo" .User}} |
{{block "name" .}}...{{end}} | Define a template with default content | {{block "content" .}}Default content{{end}} |
Functions and Pipelines
| Syntax | Description | Example |
|---|
{{func .}} | Call function with single argument | {{len .Items}} |
{{func arg1 arg2}} | Call function with multiple arguments | {{eq .Name "John"}} |
| `{{. | func}}` | Pipe value to function |
| `{{. | func1 | func2}}` |
| `{{.Field | func1 | func2}}` |
Built-in Functions
Comparison
| Function | Description | Example |
|---|
eq | Equal | {{if eq .Status "active"}}...{{end}} |
ne | Not equal | {{if ne .Status "disabled"}}...{{end}} |
lt | Less than | {{if lt .Count 5}}...{{end}} |
le | Less than or equal | {{if le .Count 10}}...{{end}} |
gt | Greater than | {{if gt .Price 100}}...{{end}} |
ge | Greater than or equal | {{if ge .Age 18}}...{{end}} |
Logical Operations
| Function | Description | Example |
|---|
and | Logical AND | {{if and .LoggedIn .IsAdmin}}...{{end}} |
or | Logical OR | {{if or .IsAdmin .IsModerator}}...{{end}} |
not | Logical NOT | {{if not .IsDisabled}}...{{end}} |
Data Manipulation
| Function | Description | Example |
|---|
len | Length of array/slice/map/string | {{len .Items}} |
index | Get element at index | {{index .Users 0}} |
slice | Slice an array | {{slice .Items 0 5}} |
print | Concatenate and print | {{print "Hello" "World"}} |
printf | Formatted print | {{printf "%.2f" .Price}} |
println | Print with newline | {{println .Message}} |
Text/HTML Context
| Package | Description | Example |
|---|
text/template | General text processing | import "text/template" |
html/template | HTML-specific with auto-escaping | import "html/template" |
HTML Template Types
| Type | Description | Example |
|---|
template.HTML | Unescaped HTML | template.HTML("<b>Bold</b>") |
template.CSS | Unescaped CSS | template.CSS("color: red;") |
template.JS | Unescaped JavaScript | template.JS("alert('Hello')") |
template.URL | Unescaped URL | template.URL("https://example.com") |
template.Srcset | Unescaped srcset attribute | template.Srcset("img.jpg 1x") |
Common Template Patterns
Layout with Blocks
// base.tmpl
<!DOCTYPE html>
<html>
<head>
<title>{{block "title" .}}Default Title{{end}}</title>
</head>
<body>
<header>{{block "header" .}}Default Header{{end}}</header>
<main>{{block "content" .}}Default Content{{end}}</main>
<footer>{{block "footer" .}}Default Footer{{end}}</footer>
</body>
</html>
// page.tmpl
{{define "title"}}Page Title{{end}}
{{define "content"}}
<h1>Custom Content</h1>
<p>This is the page content.</p>
{{end}}
Reusable Components
// components.tmpl
{{define "button"}}
<button class="btn {{.Class}}" type="{{.Type}}">{{.Text}}</button>
{{end}}
// Usage:
{{template "button" dict "Class" "primary" "Type" "submit" "Text" "Save"}}
{{if gt .TotalPages 1}}
<div class="pagination">
{{if .HasPrevious}}
<a href="?page={{.PrevPage}}">« Previous</a>
{{else}}
<span class="disabled">« Previous</span>
{{end}}
{{range $i := .PageNumbers}}
{{if eq $i $.CurrentPage}}
<span class="current">{{$i}}</span>
{{else}}
<a href="?page={{$i}}">{{$i}}</a>
{{end}}
{{end}}
{{if .HasNext}}
<a href="?page={{.NextPage}}">Next »</a>
{{else}}
<span class="disabled">Next »</span>
{{end}}
</div>
{{end}}
{{define "field"}}
<div class="form-group {{if .Error}}has-error{{end}}">
<label for="{{.Name}}">{{.Label}}{{if .Required}} *{{end}}</label>
<input
type="{{.Type}}"
name="{{.Name}}"
id="{{.Name}}"
value="{{.Value}}"
{{if .Required}}required{{end}}
>
{{if .Error}}
<div class="error">{{.Error}}</div>
{{end}}
</div>
{{end}}
// Usage:
{{template "field" dict "Name" "email" "Label" "Email Address" "Type" "email" "Value" .Email "Required" true "Error" .Errors.email}}
Error Handling
// Parse template with error handling
tmpl, err := template.New("example").Parse(templateText)
if err != nil {
// Handle parsing error
log.Fatal("Template parsing error:", err)
}
// Execute template with error handling
err = tmpl.Execute(outputWriter, data)
if err != nil {
// Handle execution error
log.Fatal("Template execution error:", err)
}
// Use template.Must for templates that must be valid
var tmpl = template.Must(template.New("example").Parse(templateText))
Using template.FuncMap
funcMap := template.FuncMap{
"upper": strings.ToUpper,
"lower": strings.ToLower,
"title": strings.Title,
"add": func(a, b int) int {
return a + b
},
"formatDate": func(t time.Time) string {
return t.Format("Jan 02, 2006")
},
}
tmpl := template.New("example").Funcs(funcMap)
tmpl, err := tmpl.Parse(templateText)
Template Helper Structs
// Define helper methods on types
type User struct {
FirstName string
LastName string
BirthDate time.Time
}
func (u User) FullName() string {
return u.FirstName + " " + u.LastName
}
func (u User) Age() int {
return int(time.Since(u.BirthDate).Hours() / 24 / 365)
}
// In template:
{{.FullName}} (Age: {{.Age}})