本文介绍go语言中的模板template渲染
文章目录
1. 渲染模板
1.1 模板路径
相对路径
相对路径都是基于 $GOPATH/src/
例如 ./index.html
的路径将被解析为$GOPATH/src/index.html
绝对路径没什么好说的,写对地址就好
1.2 模板渲染的方法
模板渲染使用方法
template.ParseFiles
http.HandleFunc("/temp", func(writer http.ResponseWriter, request *http.Request) {
t := template.Must(template.ParseFiles("E:/goproject/src/gostudy/temp/index.html"))
data := struct{
Name string
}{
"zhangsan"
}
t.Execute(writer, data) //执行模板的merger操作
})
http.ListenAndServe(":8080", nil)
2. 变量解析
假设定义结构体如下
import (
"html/template"
"net/http"
)
type Test struct {
HTML string
SafeHTML template.HTML
Title string
Path string
Dog Dog
Map map[string]string
}
type Dog struct {
Name string
Age int
}
data := Test{
HTML: "<h1>一级标题</h1>",
SafeHTML: template.HTML("<h1>安全的标题</h1>"),
Title: "会被转义的斜杠 \"\\\" ",
Path: "/dashboard/settings",
Dog: Dog{"大黄", 6},
Map: map[string]string{
"username": "张三",
"age": 12,
},
}
普通标签下:
{{.}}
: 打印所有模板变量
{{.Dog.Name}}
: 打印单个变量名称
script标签如下:
<script>
var dog = {{.Dog}};
var map = {{.Map}};
alert({{.Title}});
</script>
我们会发现,结构体和map会自动转换成json对象,字符串则会自动加上双引号,不需要我们手动添加
<script>
var dog = {"Name":"大黄","Age":6};
var map = {"job":"计算机工程师","username":"张三"};
alert("会被转义的斜杠 \"\\\" ");
</script>
3. 模板嵌套及变量传递
3.1 定义模板
{{ define "template_name" }}
...模板内容
{{ end }}
3.2 引入模板
{{template "template_name" . }}
第一个参数是定义模板的名称,第二个参数是 传递的变量
.
是所有变量,也可以指定特定的变量
如果不传递此参数,模板中将不会解析变量
3.3 指定解析模板
path := "E:/goproject/src/gostudy/temp/"
t := template.Must(template.ParseFiles(path+"header.html",path+"index.html",path+"footer.html"))
data := struct{
Name string
Title string
}{
"张三",
"测试模板index",
}
t.ExecuteTemplate(writer,"index", data)
3.4 实例
比如我们有三个模板,分别是 index.html
/header.html
/footer.html
分解图如下
4. 循环分支和函数的使用
4.1 循环
指定kv的循环
{{range $k, $v := .slice}}
{{$v}}
{{end}}
只需要v的循环
{{range .slice}}
{{.}} //这里需要引用循环外变量需要使用 `$.`代替`.`
{{end}}
4.2 判断
{{if .condition }}
...
{{else if .condition }}
...
{{else}}
...
{{end}}
操作符 | 说明 | 示例 |
---|---|---|
and |
且 | {{if and con1 con2 }} ... {{end}} |
or |
或 | {{if or con1 con2 }} ... {{end}} |
not |
非 | {{if not con }} ... {{end}} |
eq |
等于 | {{if eq con1 con2 }} ... {{end}} |
ne |
不等于 | {{if ne con1 con2 }} ... {{end}} |
lt |
小于 | {{if lt con1 con2 }} ... {{end}} |
le |
小于等于 | {{if le con1 con2 }} ... {{end}} |
gt |
大于 | {{if gt con1 con2 }} ... {{end}} |
ge |
大于等于 | {{if ge con1 con2 }} ... {{end}} |
4.3 函数
说到函数,模板中很多内置函数是可以直接使用的,也就是是否引入包都无关的函数 如 :
len
但是如果是自定义的函数,如 你想判断你的爱好是否存在于某一个slice
中
你的自定义函数
func FindInt(s []int, i int) bool {
res := sort.SearchInts(s,i)
if len(s) == res {
return false
}
return true
}
你的模板
<div class="form-group">
<label class="col-sm-2 control-label no-padding-right" > 爱好</label>
<div class="col-sm-10">
<input name="hobby" type="checkbox" value="1" {{if (FindInt .Hobby 1) }}checked{{end}} /> 足球
<input name="hobby" type="checkbox" value="2" {{if (FindInt .Hobby 2) }}checked{{end}} /> 篮球
<input name="hobby" type="checkbox" value="3" {{if (FindInt .Hobby 3) }}checked{{end}} /> 羽毛球
<span class="red">*</span>
</div>
</div>
这时候编译模板会报 undefined func FindInt
, 你需要在编译模板之前,将你的函数配置进 Funcs
操作如下
path := "E:/goproject/src/gostudy/temp/"
t := template.New("form.html").Funcs(template.FuncMap{"FindInt":FindInt})
t = template.Must(t.ParseFiles(path+"form.html"))
4.4 自定义变量
使用
$
定义变量
{{$varname := .Name}}
使用
with
定义局部变量with ... end
中包含的.
即指代with
后面的值
{{with "hello"}}
{{.}}
{{end}}
4.5 示例
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>