这是我参与「第五届青训营 」伴学笔记创作活动的第14天
模板嵌套
自定义函数
func sayHello(w http.ResponseWriter, r *http.Request) {
htmlByte, err := ioutil.ReadFile("./hello.tmpl")
if err != nil {
fmt.Println("read html failed, err:", err)
return
}
// 自定义一个夸人的模板函数
kua := func(arg string) (string, error) {
return arg + "真帅", nil
}
// 采用链式操作在Parse之前调用Funcs添加自定义的kua函数
tmpl, err := template.New("hello").Funcs(template.FuncMap{"kua": kua}).Parse(string(htmlByte))
if err != nil {
fmt.Println("create template failed, err:", err)
return
}
user := User{
Name: "小王子",
Gender: "男",
Age: 18,
}
// 使用user渲染模板,并将结果写入w
tmpl.Execute(w, user)
}
或者分开写
//定义模板
t:=template.New("hello.tmpl")
//向模板引擎添加自定义函数
t.Funcs(template.FuncMap{
"kua":kua, //"kua"可以写成新的名字
})
//解析模板
_,err:=t.ParseFiles("./hello.tmpl")
我们可以在模板文件hello.tmpl中按照如下方式使用我们自定义的kua函数了。
{{kua .Name}}
嵌套模板template
在template中嵌套其他的template。这个template可以是单独的文件,也可以是通过define定义的template t.tmpl
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>tmpl test</title>
</head>
<body>
<h1>测试嵌套template语法</h1>
<hr>
{{template "ul.tmpl"}}
<hr>
{{template "ol.tmpl"}}
</body>
</html>
{{ define "ol.tmpl"}}
<ol>
<li>吃饭</li>
<li>睡觉</li>
<li>打豆豆</li>
</ol>
{{end}}
u1.tmpl
<ul>
<li>注释</li>
<li>日志</li>
<li>测试</li>
</ul>
main函数注册一个tmplDemo路由处理函数: http.HandleFunc("/tmpl", tmplDemo)
func tmplDemo(w http.ResponseWriter, r *http.Request) {
tmpl, err := template.ParseFiles("./t.tmpl", "./ul.tmpl")
//被嵌套的模板一定要在后面解析
if err != nil {
fmt.Println("create template failed, err:", err)
return
}
user := User{
Name: "小明",
Gender: "男",
Age: 18,
}
tmpl.Execute(w, user)
}
模板继承
block
很多页面的大体布局相同,只有部分区别
{{block "name" pipeline}} T1 {{end}}
block是定义模板{{define "name"}} T1 {{end}}和执行{{template "name" pipeline}}缩写。 典型的用法是定义一组根模板,然后通过在其中重新定义块模板进行自定义。
定义一个根模板templates/base.tmpl
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>模板继承</title>
</head>
<style>
*{
margin: 0;
}
.nav{
height: 50px;
width: 100%;
position: fixed;
background-color: aqua;
top: 0;
}
.main{
margin-top: 50px;
}
.menu{
width: 20%;
height: 100%;
position: fixed;
left: 0;
background-color: aquamarine;
}
.center{
text-align: center;
}
</style>
<body>
<div class="nav"></div>
<div class="main">
<div class="menu"></div>
<div class="content center">
{{block "content" . }}{{end}}
</div>
</div>
</body>
</html>
然后定义一个templates/index.tmpl,”继承”base.tmpl:
{{template "base.tmpl" .}} //.一定要加,继承数据
{{define "content"}}
<div>Hello world!</div>
<p>This index</p>
{{end}}
然后使用template.ParseGlob按照正则匹配规则解析模板文件,然后通过ExecuteTemplate渲染指定的模板:
func index(w http.ResponseWriter, r *http.Request){
//tmpl, err := template.ParseGlob("./*.tmpl") //全解析
tmpl, err :=template.ParseFiles("./base.tmpl","./index.tmpl") //选定解析
if err != nil {
fmt.Println("create template failed, err:", err)
return
}
msg:="This is index"
err = tmpl.ExecuteTemplate(w, msg, nil)//指定渲染的模板
if err != nil {
fmt.Println("render template failed, err:", err)
return
}}
如果我们的模板名称冲突了,例如不同业务线下都定义了一个index.tmpl模板
*1. 在模板文件开头使用{{define 模板名}}语句显式的为模板命名。
*2. 可以把模板文件存放在templates文件夹下面的不同目录中,然后使用template.ParseGlob("templates/**/*.tmpl")解析模板。
修改默认标识符 Go标准库的模板引擎使用的花括号{{和}}作为标识,而许多前端框架(如Vue和 AngularJS)也使用{{和}}作为标识符, 发生冲突
template.New("test").Delims("{[", "]}").ParseFiles("./t.tmpl")
temp,err :=template.New("index.tmpl").Delims("{[","]}").ParseFiles("./index.tmpl")