🎭 Go Templates: Your Magic Fill-in-the-Blank Machine
The Big Picture
Imagine you have a birthday card that says:
“Happy Birthday, ______! You are ____ years old today!”
You just fill in the blanks with different names and ages for different friends. That’s exactly what Go templates do!
Templates are like fill-in-the-blank pages. You write the structure once, then Go fills in the blanks with real data. Super useful for websites, emails, reports—anything where the format stays the same but the details change.
🎯 What We’ll Learn
graph TD A["Go Templates"] --> B["text/template"] A --> C["html/template"] A --> D["Template Basics"] B --> E["Plain text output"] C --> F["Safe HTML output"] D --> G["Actions & Variables"] D --> H["Pipelines"] D --> I["Control Flow"]
📦 The Two Template Packages
Go gives you two template packages. Think of them as two different crayons:
| Package | What It’s For | Safety Level |
|---|---|---|
text/template |
Plain text (emails, configs) | Basic |
html/template |
Web pages (HTML) | Super safe |
Why Two?
The html/template package is special. It protects your website from bad guys who try to inject harmful code. It automatically escapes dangerous characters!
🔤 text/template Package
This is your basic crayon. Use it when you’re NOT making web pages.
Your First Template
package main
import (
"os"
"text/template"
)
func main() {
// Create a template
tmpl := template.New("greeting")
// Define the pattern
tmpl, _ = tmpl.Parse(
"Hello, {{.Name}}!")
// Fill in the blank
data := map[string]string{
"Name": "Alex",
}
tmpl.Execute(os.Stdout, data)
}
Output: Hello, Alex!
🎈 What Just Happened?
- Create a new template with a name
- Parse your pattern (the
{{.Name}}is the blank) - Execute fills the blank with real data
The {{.Name}} is like saying “put the Name value here!”
Multiple Blanks
tmpl, _ := template.New("card").Parse(
`Dear {{.Name}},
Happy {{.Event}}!
From, {{.Sender}}`)
data := map[string]string{
"Name": "Sam",
"Event": "Birthday",
"Sender": "Mom",
}
tmpl.Execute(os.Stdout, data)
Output:
Dear Sam,
Happy Birthday!
From, Mom
🛡️ html/template Package
This is your safety crayon. Use it for web pages!
Why Is It Safer?
Imagine someone types this as their name:
<script>alert('Hacked!')</script>
With text/template, this dangerous code runs!
With html/template, Go turns it into safe text:
<script>alert('Hacked!')</script>
The bad code becomes harmless letters. Magic!
Using html/template
package main
import (
"os"
"html/template"
)
func main() {
tmpl, _ := html.template.New("page").
Parse("<h1>Hello, {{.Name}}!</h1>")
data := map[string]string{
"Name": "World",
}
tmpl.Execute(os.Stdout, data)
}
Output: <h1>Hello, World!</h1>
🎯 The Golden Rule
Building a website? Always use
html/template!Making configs, emails, plain text? Use
text/template.
🧱 Template Basics
Now let’s learn the building blocks!
1. The Dot (.)
The dot is like a pointer saying “look at this data!”
// If your data is just a string
tmpl.Parse("Hello, {{.}}!")
tmpl.Execute(os.Stdout, "World")
// Output: Hello, World!
// If your data is a struct
type Person struct {
Name string
Age int
}
tmpl.Parse("{{.Name}} is {{.Age}}")
tmpl.Execute(os.Stdout, Person{
Name: "Luna", Age: 10,
})
// Output: Luna is 10
2. Actions: The {{ }} Braces
Everything inside {{ }} is an action. It tells Go what to do!
| Action | What It Does |
|---|---|
{{.Field}} |
Print a field |
{{.}} |
Print everything |
{{/* comment */}} |
A hidden note |
3. Variables
You can create variables inside templates!
tmpl.Parse(`
{{$name := .Name}}
Hello, {{$name}}! Nice to meet you, {{$name}}!
`)
Variables start with $. Use := to create them.
4. Pipelines
Pipelines are like assembly lines. Data flows through them!
// The | symbol passes data to the next function
tmpl.Parse(`{{.Name | printf "%q"}}`)
// Output: "Luna" (with quotes!)
Think of it like:
.Name → printf "%q" → Output
Luna → "Luna" → Screen
You can chain multiple pipes:
{{.Text | html | printf "%s"}}
5. If/Else (Making Decisions)
tmpl.Parse(`
{{if .IsHappy}}
😊 Yay!
{{else}}
😢 Oh no!
{{end}}
`)
Templates can think! They check conditions and show different things.
Comparisons
{{if eq .Score 100}}Perfect!{{end}}
{{if gt .Age 18}}Adult{{end}}
{{if lt .Price 10}}Cheap!{{end}}
| Function | Meaning |
|---|---|
eq |
equals |
ne |
not equals |
lt |
less than |
gt |
greater than |
le |
less or equal |
ge |
greater or equal |
6. Range (Loops)
Want to show a list? Use range!
tmpl.Parse(`
My Friends:
{{range .Friends}}
- {{.}}
{{end}}
`)
data := map[string][]string{
"Friends": {"Alex", "Sam", "Pat"},
}
Output:
My Friends:
- Alex
- Sam
- Pat
Range with Index
{{range $i, $friend := .Friends}}
{{$i}}: {{$friend}}
{{end}}
Output:
0: Alex
1: Sam
2: Pat
7. With (Changing Focus)
with changes what the dot (.) points to:
tmpl.Parse(`
{{with .Pet}}
Pet Name: {{.Name}}
Pet Age: {{.Age}}
{{end}}
`)
Inside {{with .Pet}}, the dot means .Pet!
8. Template Functions
Go gives you helpful functions:
// Get the length of something
{{len .Items}} items
// Print formatted text
{{printf "Score: %d" .Score}}
// Check if something exists
{{if .Name}}Has name!{{end}}
9. Defining Sub-Templates
Break big templates into small pieces!
tmpl.Parse(`
{{define "header"}}
<h1>Welcome!</h1>
{{end}}
{{define "page"}}
{{template "header"}}
<p>Content here</p>
{{end}}
`)
tmpl.ExecuteTemplate(os.Stdout, "page", nil)
Output:
<h1>Welcome!</h1>
<p>Content here</p>
🗂️ Loading Templates from Files
Real projects keep templates in files!
// Load one file
tmpl, err := template.ParseFiles(
"greeting.html")
// Load many files
tmpl, err := template.ParseFiles(
"header.html",
"footer.html",
"page.html",
)
// Load all files matching pattern
tmpl, err := template.ParseGlob(
"templates/*.html")
🎨 Complete Example
Let’s build a simple webpage!
template.html:
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
<h1>{{.Title}}</h1>
{{if .Items}}
<ul>
{{range .Items}}
<li>{{.}}</li>
{{end}}
</ul>
{{else}}
<p>No items yet!</p>
{{end}}
</body>
</html>
main.go:
package main
import (
"html/template"
"os"
)
func main() {
tmpl, _ := template.ParseFiles(
"template.html")
data := map[string]interface{}{
"Title": "My Shopping List",
"Items": []string{
"Apples",
"Bananas",
"Cookies",
},
}
tmpl.Execute(os.Stdout, data)
}
🧠 Remember This!
graph TD A["Start"] --> B{Making HTML?} B -->|Yes| C["Use html/template"] B -->|No| D["Use text/template"] C --> E["Auto-escapes bad code!"] D --> F["Plain text output"]
| Concept | Remember It As |
|---|---|
{{.}} |
The spotlight - points to data |
{{range}} |
The loop - repeat for each item |
{{if}} |
The chooser - pick one path |
{{with}} |
The focuser - zoom into data |
{{template}} |
The includer - insert another piece |
Pipes | |
Assembly line - chain functions |
🚀 You Did It!
You now understand Go templates! You can:
✅ Use text/template for plain text
✅ Use html/template for safe web pages
✅ Fill in blanks with {{.Field}}
✅ Loop through lists with {{range}}
✅ Make decisions with {{if}}
✅ Chain data through pipelines
✅ Build reusable sub-templates
Templates are your fill-in-the-blank superpower. Go build something amazing! 🎉
