Templates
Templates are a powerful way to separate the presentation layer from your code logic. The text/template and html/template packages provide functionalities for parsing and executing text and HTML templates. Templates are useful for rendering dynamic content in web applications or generating structured text documents.
html/template package
The html/template package provides additional HTML-specific features and ensures proper escaping for HTML content.
When you use template.Must, it helps simplify error handling when parsing templates. It panics if the template parsing fails, eliminating the need to explicitly check for errors. However, this approach is suitable only during initialization, and the application should terminate if the templates cannot be parsed properly.
Example
package main
import (
"fmt"
htmlTemplate "html/template"
"os"
textTemplate "text/template"
)
type Person struct {
Name string
Age int
}
func main() {
tmpl, err := textTemplate.New("temple-string").Parse("Hello, {{ .Name }}")
if err != nil {
panic(err)
}
data := struct {
Name string
}{
Name: "Gabriel",
}
tmpl.Execute(os.Stdout, data)
fmt.Println("\n************")
persons := [4]Person{
{Name: "Gabriel", Age: 15},
{Name: "Cassio", Age: 40},
{Name: "Yuri", Age: 20},
{Name: "Lucas", Age: 17},
}
tmpl_html := htmlTemplate.Must(
htmlTemplate.New("person.html").ParseFiles("person.html"))
tmpl_html.Execute(os.Stdout, persons)
}
Compose Templates
You can compose templates by defining reusable parts and embedding them within other templates. This helps in creating modular and maintainable templates.
Example
package main
import (
"html/template"
"net/http"
)
type Person struct {
Name string
Age int
}
func main() {
base_template := template.Must(template.ParseFiles(
"header.html",
"person.html",
"footer.html",
))
persons := [4]Person{
{Name: "Gabriel", Age: 15},
{Name: "Cassio", Age: 40},
{Name: "Yuri", Age: 20},
{Name: "Lucas", Age: 17},
}
http.HandleFunc("/", func(res http.ResponseWriter, request *http.Request) {
err := base_template.ExecuteTemplate(res, "header.html", persons)
if err != nil {
panic(err)
}
})
http.ListenAndServe(":8080", nil)
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Persons</title>
</head>
<body>
<p>All Users:</p>
<h1>Hello, Gabriel!</h1>
<p>Age: 15</p>
<h1>Hello, Cassio!</h1>
<p>Age: 40</p>
<p>Adult User</p>
<h1>Hello, Yuri!</h1>
<p>Age: 20</p>
<p>Adult User</p>
<h1>Hello, Lucas!</h1>
<p>Age: 17</p>
<div>
<p>A nice footer here!</p>
</div>
</body>
</html>
Passing Functions
You can define and use functions with the Funcs field of the template to perform various operations on data. The FuncMap type is used to define a map of template functions.
Example
package main
import (
"html/template"
"os"
"strings"
)
type Person struct {
Name string
Age int
}
func printName(s string) string {
return "Dear " + s
}
func main() {
t := template.New("person_func.html")
t.Funcs(template.FuncMap{"upperString": strings.ToUpper})
t.Funcs(template.FuncMap{"printName": printName})
persons := [4]Person{
{Name: "Gabriel", Age: 15},
{Name: "Cassio", Age: 40},
{Name: "Yuri", Age: 20},
{Name: "Lucas", Age: 17},
}
t = template.Must(t.ParseFiles("person_func.html"))
t.Execute(os.Stdout, persons)
}