渲染模板
- 定义一个默认模板index.tpl,并写入内容hello world
Hello World
- 定义一个方法渲染默认模板
1、noescape 模板函数可将字符串解析转义成 html。
2、必须设置输出内容为 text/html,不然有些内容不能正常渲染。
3、loadTemplate是自己封装的用来加载特定路径模板文件的方法,可根据实际情况自己封装。
func Index(w http.ResponseWriter, r *http.Request) {
funcMap := template.FuncMap{
"noescape": func(s string) template.HTML {
return template.HTML(s)
},
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
tpl, err := template.New("index.html").Funcs(funcMap).ParseFiles(loadTemplate("index.html"))
if err != nil {
log.Println(err)
return
}
tpl.Execute(w, nil)
return
}
模板嵌套
- 定义一个最外层模板layout.tpl
{{define "layout"}}
{{template "body" .}} # 加载body模板内容
{{end}}
- 定义一个需要加载的模板body.tpl
{{template "layout" .}} # 加载layout模板内容
{{define "body"}} # 定义body模板的内容,在里面的数据将会渲染到layout模板中
Hello world
{{end}}
- 定义渲染模板的方法
1、template.new(“body.tpl”)参数必须是子模板的文件名,不然解析仍然会不成功。
2、ParseFiles 参数必须将layout.tpl模板放在最后一个参数。
func Index(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
tpl, err := template.New("body.tpl").ParseFiles(loadTemplate("body.tpl"), loadTemplate("layout.tpl"))
if err != nil {
return
}
tpl.Execute(w, data)
return
}
http请求实现加载模板片段
- 定义一个最外层模板layout.tpl
{{define "layout"}}
{{template "body" .}} # 加载body模板内容
{{require (sprintf "/test/?msg=%s" "world 2") | noescape}} # require 模板函数实现加载模板片段,sprintf 函数实现字符串格式化
{{end}}
- 定义一个需要加载的模板body.tpl
{{template "layout" .}} # 加载layout模板内容
{{define "body"}} # 定义body模板的内容,在里面的数据将会渲染到layout模板中
Hello world
{{end}}
- 定义渲染模板的方法
1、require 是一个模板函数,通过请求接口获取到片段模板字符串,然后通过 noescape 将模板字符串解析成html。
2、sprintf 是一个模板函数,用来格式化字符串。
// 加载模板
func Index(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
tpl, err := template.New("body.tpl").Funcs(funcMap()).ParseFiles(loadTemplate("body.tpl"), loadTemplate("layout.tpl"))
if err != nil {
return
}
tpl.Execute(w, nil)
return
}
// require 请求接口,获取模板片段
func Test(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
var html = fmt.Sprintf(`Hello %s`, r.Url.Query().Get("msg"))
tpl, err := template.New("body.tpl").Funcs(funcMap()).ParseFiles(loadTemplate("body.tpl"), loadTemplate("layout.tpl"))
if err != nil {
return
}
tpl.Execute(w, nil)
return
}
// require 函数定义,并加入到模板函数中
func httpGet(path string) (html string) {
resp, err := http.Get(fmt.Sprintf("http://%s:%d%s", configs.Cfg.Web.Host, configs.Cfg.Web.Port, path)) // 请求接口地址
if err != nil {
log.Println(err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err)
return
}
return string(body)
}
// funcMap定义
func funcMap() template.FuncMap {
return template.FuncMap{
"noescape": func(s string) template.HTML {
return template.HTML(s)
},
"html2text": helper.ExtractTextFromHtml,
"require": httpGet,
"join": join,
"sprintf": fmt.Sprintf,
}
}
模板语法
- 基本判断(eq,neq,lte,le…)
{{if eq .a 1}}
如果 a === 1,就会打印这个字符串,其他语法用法类似
{{end}}
- 模板函数
{{funcName .var1 .var2}}
此处调用函数funcName,有两个参数,依次是var1,var2
{{end}}
- 遍历(range)
{{range .}}
此处可以用 . 表示各项值,可以用 $. 引用外部参数
{{end}}
{{range $k, $v := .}}
此处 $k 表示 . 的索引值,$v 表示 . 的值
{{end}}
- with封装,可创建一个封闭的作用域
{{ with arg }}
此处的点 . 就是arg
{{ end }}
// with 也可以用else,两个点的作用域是一致的
{{ with ""}}
Now the dot is set to {{ . }}
{{ else }}
{{ . }}
{{ end }}
- 打印
{{print .item}} // 打印item的内容
- 模板中定义变量
可以使用 $variable := value 设置变量,其中在range迭代的过程中,就已经使用了设置变量的方式。
- 管道
// 使用管道将自定义函数连在一起
{{ p1 | p2 | p3 }}
// 使用管道符自定义格式化输出
{{ 12.3456 | printf "%.2f" }}