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
Title
field 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
IsAdmin
istrue
. If it is, the first block (<p>You have admin privileges!</p>
) is rendered. If not, the block underelse
is rendered.
- Conditional statement to check if
-
{{range .Items}}...{{end}}
:- Loops over the
Items
field, 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
with
action sets the context toContact
temporarily. Inside the block, you can refer to fields ofContact
directly (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" .}}
:define
creates a named template (footer
in 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
upper
to convert text to uppercase). You would need to define theupper
function when parsing the template in Go usingFuncs
method.
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))}