Templates

Back

Loading concept...

🎭 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?

  1. Create a new template with a name
  2. Parse your pattern (the {{.Name}} is the blank)
  3. 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:

&lt;script&gt;alert('Hacked!')&lt;/script&gt;

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! 🎉

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.