Loading...
Loading...

Go Templates Tutorial

Go's template packages (text/template and html/template) provide powerful tools for generating dynamic content. This tutorial covers template syntax, actions, functions and security considerations.

1. Basic Templates

1.1 Creating and Executing Templates

The simplest template example with variable substitution:

package main

import (
    "os"
    "text/template"
)

func main() {
    // Define template
    tmpl := `Hello, {{.Name}}! Today is {{.Day}}.`

    // Create template object
    t := template.Must(template.New("greeting").Parse(tmpl))

    // Execute with data
    data := struct {
        Name string
        Day  string
    }{
        Name: "Alice",
        Day:  "Monday",
    }
    t.Execute(os.Stdout, data)
}

Key Concepts:

  • {{.Field}}: Accesses data fields
  • template.New(): Creates new template
  • Parse(): Compiles template text
  • Execute(): Renders template with data

2. Template Actions

2.1 Conditionals

Control template flow with if/else statements:

const tmpl = `
{{if .User.IsAdmin}}
    <p>Welcome ADMIN {{.User.Name}}</p>
{{else if .User.IsLoggedIn}}
    <p>Welcome back {{.User.Name}}</p>
{{else}}
    <p>Please log in</p>
{{end}}`

2.2 Loops

Iterate over slices, arrays and maps:

const tmpl = `
<ul>
{{range .Items}}
    <li>{{.}}</li>
{{else}}
    <li>No items found</li>
{{end}}
</ul>`

Range Features:

  • {{range .}}: Iterates over collection
  • {{.}}: Current item in loop
  • {{else}}: Executes if collection empty

3. Template Functions

3.1 Built-in Functions

Go templates include useful built-in functions:

const tmpl = `
{{len .Items}} items total
{{index .Names 2}} is the 3rd name
{{printf "Price: $%.2f" .Price}}
{{html "<script>alert()</script>"}}`

3.2 Custom Functions

Extend templates with your own functions:

func main() {
    funcMap := template.FuncMap{
        "uppercase": strings.ToUpper,
        "add": func(a, b int) int { return a + b },
    }

    t := template.Must(
        template.New("").Funcs(funcMap).Parse(
            `{{uppercase .Name}} ({{add .A .B}})`,
        ),
    )
    
    t.Execute(os.Stdout, map[string]interface{}{
        "Name": "hello",
        "A":    5,
        "B":    3,
    })
}

4. HTML Templates

4.1 Auto-escaping

The html/template package automatically escapes content:

package main

import (
    "html/template"
    "os"
)

func main() {
    const tpl = `
    <h1>{{.Title}}</h1>
    <p>{{.Content}}</p>`

    t := template.Must(template.New("webpage").Parse(tpl))

    data := struct {
        Title   string
        Content string
    }{
        Title:   "My Page",
        Content: "<script>alert('xss')</script>",
    }

    t.Execute(os.Stdout, data)
}

Security Features:

  • Automatic HTML escaping
  • Context-aware sanitization
  • Safe against XSS attacks

5. Template Inheritance

5.1 Base Templates

Create reusable template layouts with blocks:

// base.html
{{define "base"}}
<html>
<head>
    <title>{{block "title" .}}Default Title{{end}}</title>
</head>
<body>
    {{block "content" .}}Default content{{end}}
</body>
</html>
{{end}}

// page.html
{{define "title"}}My Page{{end}}
{{define "content"}}
    <h1>Welcome</h1>
    <p>Page content here</p>
{{end}}`

5.2 Template Composition

Combine templates using the template action:

func main() {
    // Parse all template files
    t := template.Must(template.ParseFiles("base.html", "page.html"))
    
    // Execute specific template
    t.ExecuteTemplate(os.Stdout, "base", nil)
}

6. Best Practices

6.1 Template Organization

  • Keep templates in separate .tmpl files
  • Use a templates directory
  • Group related templates together

6.2 Error Handling

// Proper template initialization
t, err := template.New("email").Parse(tmpl)
if err != nil {
    log.Fatalf("Failed to parse template: %v", err)
}

// Safe execution
err = t.Execute(os.Stdout, data)
if err != nil {
    log.Printf("Template execution failed: %v", err)
}

6.3 Performance Considerations

// Parse templates once at startup
var templates = template.Must(template.ParseGlob("templates/*.tmpl"))

// Then reuse the parsed templates
func renderTemplate(w http.ResponseWriter, name string, data interface{}) {
    err := templates.ExecuteTemplate(w, name+".tmpl", data)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}
0 Interaction
0 Views
Views
0 Likes
×
×
×
🍪 CookieConsent@Ptutorials:~

Welcome to Ptutorials

$ Allow cookies on this site ? (y/n)

top-home