Golang: Template
Bài đăng này đã không được cập nhật trong 5 năm
Getting Start
The Go standard library provides a set of packages to generate output. The text/template
package implements templates for generating text output, while the html/template
package implements templates for generating HTML output that is safe against certain attacks. Both packages use the same interface but the following examples of the core features are directed towards HTML applications.
Parsing
To create and store a template in a variable so that we can execute it later on we use Go standard library function template.New
allocate a new undefined template with associated name.
import "html/template"
template.New(name)
To create a template with template body use the template.ParseFiles
version, which accepts multiple files a argument.
import "html/template"
template.ParseFiles(files...)
There is also a (*template.Template) Clone()
method which allocate a new template based on exiting template.
tmpl, err := template.ParseFiles(files...)
if err != nil {
panic(err)
}
newTmpl, err := template.Clone()
After a template is parsed then we are ready for the next section.
Executing
There are two step processes needed in order to generate html content. The first step is to parse a template, which we've just covered. The last step is to execute that pre-define template with associated data to get the final output. To do that we call Execute
or ExecuteTemplate
func homeHandler(w http.ResponseWriter, r *http.Request) {
d := struct {
Name string
} {
Name: "Jonh due",
}
tmpl, _ := template.ParseFiles("home.html")
tmpl.Execute(w, d)
}
Let see how to show data inside of template. The .
notation refer to current data object that passed into Execute
method. So the following .Name
is equivalent to d.Name
.
<h1>Hello, {{.Name}}</h1>
The different between Execute
and ExecuteTemplate
is that ExecuteTemplate
parse named template that associated with tmpl
.
Also note that html/template
also does encoding to escape html tag so the following will be output as
// string value
"<h1>A header!</h1>"
// output
<h1>A header!</h1>
To tell template to output html tag without escaping we need to use template.HTML
function which return template.HTML
like the following
template.HTML(`<h1>A header!</h1>`)
Action
If/Else
Like any other template engine go also support conditional check with the following syntax.
{{if .IsLoggedIn}}
<h1>Hello, {{.Name}}</h1>
{{else}}
<span>Login here</span>
{{end}}
Remove Whitespace
Adding different values to a template can add various amounts of whitespace. We can either change our template to better handle it, by ignoring or minimizing effects, or we can use the minus sign -
within out template.
<h1>Hello, {{if .Name}} {{.Name}} {{- else}} Anonymous {{- end}}!</h1>
This will remove any whitespace after name.
Range
To loop through collection we can use range block with the following syntax.
type Cart struct {
Items []Item
Total float64
}
type Item struct {
Name string
Quality uint32
}
<ul class="cart-item">
{{range .Items}}
<li>{{.Name}} ({{.Quality}}</li>
{{end}}
</ul>
Function
Calling a method in a template is straightforward. Separate each argument with space.
{{.DoSomeCalculation .Arg1 .Arg2}}
For Custom function we need to create a template.FuncMap
. Here is how we create and attach custom function to a template
funcMap := template.FuncMap{
"func1": customFunc1,
"func2": customFunc2,
}
tmpl, _ := template.ParseFiles(files...)
tmpl.Funcs(funcMap)
Then in the template we can call it like this.
<div>{{func1 arg1 arg2}}</div>
<div>{{func2 arg1 arg2}}</div>
Layout
Sometime we want only a small part of our webpage to be change. In order to do that we need to create a layout. Layout composition can be achieved by using template
block and combine them into other template using ParseFiles
method.
<!-- layout.html -->
<html>
<head>
<title>{{block "title"}}{{end}}</title>
</head>
<body>
{{template "content" .}}
</body>
</html>
<!-- some_page.html -->
{{define "content"}}
<div class="container">
<p>This is some page template content</p>
</div>
{{end}}
Then we combine the two like this
tmpl, _ := template.ParseFiles("layout.html", "some_page.html")
All rights reserved