t;/div>
</body>
</html>
{{define "t2.html"}}
<div style="background-color: yellow;">
This is t2.html<br/>
This is the value of the dot in t2.html - [{{ . }}]
</div>
{{end}}
然后在handler中,只需解析t1.html一个文件即可。
func process(w http.ResponseWriter, r *http.Request) {
t, _ := template.ParseFiles("t1.html")
t.Execute(w, "Hello World!")
}
block块
{{block "name" pipeline}} T1 {{end}}
A block is shorthand for defining a template
{{define "name"}} T1 {{end}}
and then executing it in place
{{template "name" pipeline}}
The typical use is to define a set of root templates that are
then customized by redefining the block templates within.
根据官方文档的解释:block等价于define定义一个名为name的模板,并在"有需要"的地方执行这个模板,执行时将"."设置为pipeline的值。
但应该注意,block的第一个动作是执行名为name的模板,如果不存在,则在此处自动定义这个模板,并执行这个临时定义的模板。换句话说,block可以认为是设置一个默认模板。
例如:
{{block "T1" .}} one {{end}}
它首先表示{{template "T1" .}}
,也就是说先找到T1模板,如果T1存在,则执行找到的T1,如果没找到T1,则临时定义一个{{define "T1"}} one {{end}}
,并执行它。
下面是正常情况下不使用block的示例。
home.html文件内容如下:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Go Web Programming</title>
</head>
<body>
{{ template "content" }}
</body>
</html>
在此文件中指定了要执行一个名为"content"的模板,但此文件中没有使用define定义该模板,所以需要在其它文件中定义名为content的模板。现在分别在两个文件中定义两个content模板:
red.html文件内容如下:
{{ define "content" }}
<h1 style="color: red;">Hello World!</h1>
{{ end }}
blue.html文件内容如下:
{{ define "content" }}
<h1 style="color: blue;">Hello World!</h1>
{{ end }}
在handler中,除了解析home.html,还根据需要解析red.html或blue.html:
func process(w http.ResponseWriter, r *http.Request) {
rand.Seed(time.Now().Unix())
t := template.New("test")
if rand.Intn(10) > 5 {
t, _ = template.ParseFiles("home.html", "red.html")
} else {
t, _ = template.ParseFiles("home.html", "blue.html")
}
t.Execute(w,"")
}
如果使用block,那么可以设置默认的content模板。例如将原本定义在blue.html中的content设置为默认模板。
修改home.html:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Go Web Programming</title>
</head>
<body>
{{ block "content" . }}
<h1 style="color: blue;">Hello World!</h1>
{{ end }}
</body>
</html>
然后修改handler:
func process(w http.ResponseWriter, r *http.Request) {
rand.Seed(time.Now().Unix())
t := template.New("test")
if rand.Intn(10) > 5 {
t, _ = template.ParseFiles("home.html", "red.html")
} else {
t, _ = template.ParseFiles("home.html")
}
t.Execute(w,"")
}
当执行else语句块的时候,发现home.html中要执行名为content的模板,但在ParseFiles()中并没有解析包含content模板的文件。于是执行block定义的content模板。而执行非else语句的时候,因为red.html中定义了content,会直接执行red.html中的content。
block通常设置在顶级的根文件中,例如上面的home.html中。
html/template的上下文感知
对于html/template包,有一个很好用的功能:上下文感知。text/template没有该功能。
上下文感知具体指的是根据所处环境css、js、html、url的path、url的query,自