Go网络编程-Templates
跳到导航
跳到搜索
简介
Go的html/template包提供了一种丰富的HTML模板语言。它主要用于Web应用程序中,以结构化的方式在客户端浏览器中显示数据。Go模板语言的一个巨大优势是数据的自动转义。无需担心XSS攻击,因为Go会解析HTML模板并在将其显示到浏览器之前转义所有输入。
第一个模板
在Go中编写模板非常简单。这个示例展示了一个待办事项列表,用HTML中的无序列表(ul)表示。在渲染模板时,传入的数据可以是任何类型的Go数据结构。它可以是简单的字符串或数字,甚至可以是下面示例中的嵌套数据结构。要在模板中访问数据,可以通过{{.}}访问最顶层变量。花括号内的点称为管道和数据结构的根元素。
data := TodoPageData{
PageTitle: "My TODO list",
Todos: []Todo{
{Title: "Task 1", Done: false},
{Title: "Task 2", Done: true},
{Title: "Task 3", Done: true},
},
}
<h1>{{.PageTitle}}</h1>
<ul>
{{range .Todos}}
{{if .Done}}
<li class="done">{{.Title}}</li>
{{else}}
<li>{{.Title}}</li>
{{end}}
{{end}}
</ul>
控制结构
模板语言包含一组丰富的控制结构来渲染你的HTML。在这里,你将了解到最常用的一些。要获取所有可能结构的详细列表,请访问:text/template
Control Structure | Definition |
---|---|
模板:/* a comment */ | Defines a comment |
{{.}} | Renders the root element |
模板:.Title | Renders the “Title”-field in a nested element |
模板:If .Done 模板:Else 模板:End | Defines an if-Statement |
模板:Range .Todos {{.}} 模板:End | Loops over all “Todos” and renders each using {{.}} |
模板:Block “content” . 模板:End | Defines a block with the name “content” |
从文件解析模板
模板可以从字符串或磁盘上的文件中解析。通常情况是,模板是从磁盘上解析的,因此这个示例展示了如何这样做。在这个示例中,有一个与Go程序位于同一目录的模板文件layout.html。
tmpl, err := template.ParseFiles("layout.html")
// or
tmpl := template.Must(template.ParseFiles("layout.html"))
在请求处理器中执行模板
一旦从磁盘解析了模板,它就可以在请求处理器中使用了。Execute函数接受一个io.Writer用于输出模板和一个interface{}用于将数据传递给模板。当函数在http.ResponseWriter上调用时,HTTP响应的Content-Type标头会自动设置为Content-Type: text/html; charset=utf-8。
func(w http.ResponseWriter, r *http.Request) {
tmpl.Execute(w, "data goes here")
}
完整代码
package main
import (
"html/template"
"net/http"
)
type Todo struct {
Title string
Done bool
}
type TodoPageData struct {
PageTitle string
Todos []Todo
}
func main() {
tmpl := template.Must(template.ParseFiles("layout.html"))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
data := TodoPageData{
PageTitle: "My TODO list",
Todos: []Todo{
{Title: "Task 1", Done: false},
{Title: "Task 2", Done: true},
{Title: "Task 3", Done: true},
},
}
tmpl.Execute(w, data)
})
http.ListenAndServe(":80", nil)
}
<h1>{{.PageTitle}}</h1>
<ul>
{{range .Todos}}
{{if .Done}}
<li class="done">{{.Title}}</li>
{{else}}
<li>{{.Title}}</li>
{{end}}
{{end}}
</ul>