The `html/template` package in Go
In Go’s html/template package, there are several types of placeholders and actions you can use inside your HTML template to manipulate data, control flow, and format content. Below is an example template that demonstrates many of these actions, along with an explanation of what they do.
Summary of Template Actions:
{{.FieldName}}: Insert data from the context.{{if condition}}...{{else}}...{{end}}: Conditional rendering based on a value.{{range .Slice}}...{{end}}: Loop through a slice or array.{{with .Field}}...{{end}}: Set a new context and work with a specific field.{{define "name"}}...{{end}}: Define a reusable sub-template.{{template "name" .}}: Render a defined sub-template.
Template Example with Various Placeholders
index.html:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{.Title}}</title></head><body> <h1>{{.Header}}</h1> <p>{{.Message}}</p>
<p><strong>Uppercase Title:</strong> {{.Title | upper}}</p> <!-- Custom function applied -->
<h2>Conditional Example</h2> {{if .IsAdmin}} <p>You have admin privileges!</p> {{else}} <p>You are a regular user.</p> {{end}}
<h2>Loop Example</h2> <ul> {{range .Items}} <li>{{.}}</li> {{end}} </ul>
<h2>With Example</h2> {{with .Contact}} <p>Email: {{.Email}}</p> <p>Phone: {{.Phone}}</p> {{end}}
<h2>Template Action Example</h2> {{define "footer"}} <footer> <p>Footer content goes here</p> </footer> {{end}}
{{template "footer" .}} <!-- Includes the footer template --></body></html>Explanation of the Template Placeholders
-
{{.Title}}:- Placeholder that inserts the value of the
Titlefield from the data passed to the template. The dot (.) represents the current context or data passed in.
- Placeholder that inserts the value of the
-
{{if .IsAdmin}}...{{else}}...{{end}}:- Conditional statement to check if
IsAdministrue. If it is, the first block (<p>You have admin privileges!</p>) is rendered. If not, the block underelseis rendered.
- Conditional statement to check if
-
{{range .Items}}...{{end}}:- Loops over the
Itemsfield, which is expected to be a slice or array. For each item, the block is executed, and the current item is inserted where{{.}}is placed. It creates a list (<li>) for each item.
- Loops over the
-
{{with .Contact}}...{{end}}:- The
withaction sets the context toContacttemporarily. Inside the block, you can refer to fields ofContactdirectly (e.g.,{{.Email}}). This is useful when you want to extract and use sub-fields in a structured object.
- The
-
{{define "footer"}}...{{end}}and{{template "footer" .}}:definecreates a named template (footerin this case) that can be reused later withtemplate. The content inside{{define "footer"}}is the footer content, and{{template "footer" .}}will insert that defined template into the page.
-
{{.Title | upper}}:- This applies a custom function (like
upperto convert text to uppercase). You would need to define theupperfunction when parsing the template in Go usingFuncsmethod.
Example in Go:
tmpl, err := template.New("index.html").Funcs(template.FuncMap{"upper": strings.ToUpper,}).ParseFiles("index.html") - This applies a custom function (like
Example Data Structure in Go
Here’s the Go data structure that would work with this template:
package main
import ( "html/template" "log" "net/http" "strings")
type Contact struct { Email string Phone string}
type PageData struct { Title string Header string Message string IsAdmin bool Items []string Contact Contact}
func handler(w http.ResponseWriter, r *http.Request) { data := PageData{ Title: "Go Templates Demo", Header: "Welcome to Go Templates!", Message: "This page demonstrates various template features.", IsAdmin: true, Items: []string{"Item 1", "Item 2", "Item 3"}, Contact: Contact{ Email: "contact@example.com", Phone: "123-456-7890", }, }
tmpl, err := template.New("index.html").Funcs(template.FuncMap{ "upper": strings.ToUpper, }).ParseFiles("index.html") if err != nil { log.Fatal(err) }
err = tmpl.Execute(w, data) if err != nil { log.Fatal(err) }}
func main() { http.HandleFunc("/", handler) log.Fatal(http.ListenAndServe(":8080", nil))}