Go Web 学习笔记(五)模版引擎
Go Web 模版引擎
模版引擎使用
Go Web 中的模版引擎可以将一个已经写好的 HTML 文件以及相应的数据渲染好之后返回给客户端,需要用到 html/template
包(该包是 text/template
包的安全版本)。
使用 Go Web 模版引擎需要以下两个步骤:
1、对文本格式的模版进行语法分析,创建一个经过语法分析的模版结构,其中模版源既可以是一个字符串,也可以是模版文件中包含的内容。
2、执行经过语法分析的模版,将 ResponseWriter
和模版所需的 动态数据
传递给模版引擎,被调用的模版引擎会把经过语法分析的模版和传入的数据结合起来,生成出最终的 HTML,并将这些 HTML 传递给ResponseWriter。
一个简单的使用案例:
package main
import (
"html/template"
"net/http"
)
func main() {
http.HandleFunc("/testtemplate", handler)
http.ListenAndServe(":8080", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
// 解析模版文件(注意模版文件的路径信息,当前项目的路径为根路径)
//t, _ := template.ParseFiles("./template/index.html")
// 通过Must函数来让Go自动处理异常
t := template.Must(template.ParseFiles("./template/index.html"))
// 执行模版文件
t.Execute(w, "hello Template")
// 将响应数据指定在index2.html中显示(可以一次加载多个模版文件然后使用该方法指定模版引擎)
//t.ExecuteTemplate(w, "index2.html", "index2.html")
}
模版引擎动作
其中在执行模版文件的过程中需要向模版文件中传递执行的数据,此时就需要使用模版文件中的 action(动作)
Go 模版的动作就是一些嵌入到模版里面的命令,这些命令在模版中需要放到两个大括号里面 {{}},例如:
\{\{.\}\} // 传递给模版的数据
\{\{/* a comment */\}\} // 模版中的注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止,就像这里表示的一样。
接下来介绍一些常见的模版动作
条件动作
条件动作可以对 bool 类型的变量进行判断从而显示指定的内容:
// 简单if,其中的 arg 是传递给条件动作的参数,该值可以是一个字符串常量、一个变量、一个返回单个值的函数获取方法等。
\{\{if arg\}\}
要显示的内容
\{\{end\}\}
// if-else
\{\{if arg\}\}
要现实的内容
\{\{else\}\}
if条件不满足时显示的内容
\{\{end\}\}
示例:
处理器设置:
// TestIf 条件动作测试
func TestIf(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.ParseFiles("./action/if.html"))
age := 17
if age >= 18 {
t.Execute(w, true)
} else {
t.Execute(w, false)
}
}
页面显示:
\{\{if .\}\}
<div>已满十八岁</div>
\{\{else\}\}
<div>未满十八岁</div>
\{\{end\}\}
这样页面显示的内容为:未满十八岁
迭代动作
迭代动作可以对数组、切片、映射或者通道进行迭代:
// 迭代方式一,range后面的点代表未被遍历的元素,要显示的内容里面的点代表的是遍历到的元素
\{\{range .\}\}
遍历到的元素是 \{\{.\}\}
\{\{end\}\}
// 迭代方式二:
\{\{range .\}\}
遍历到的元素是
\{\{else\}\}
没有任何元素
\{\{end\}\}
// 迭代map的时候可以设置变量,变量以 $ 开头
\{\{range $k,$v := .\}\}
键是:\{\{$k\}\} 值是:\{\{$v\}\}
\{\{end\}\}
// 迭代管道
// c1、c2、c3可以是参数或者函数,管道允许用户将一个参数的输出传递给下一个参数,各个参数之间使用 | 分割
\{\{c1|c2|c3\}\}
示例:
处理器设置:
// TestRange 迭代动作测试
func TestRange(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.ParseFiles("./action/range.html"))
data := []string{"苹果", "西瓜", "香蕉", "橘子"}
t.Execute(w, data)
}
界面显示:
当前的水果有:<br>
<ul>
\{\{range .\}\}
<li>\{\{.\}\}</li>
\{\{end\}\}
</ul>
设置动作
设置动作允许在指定的范围内对点(.)设置值
// 格式一
\{\{with arg\}\}
传递过来的数据设置的新值为:\{\{.\}\}
\{\{end\}\}
// 格式二
// with "" 表示没有修改,则会执行 else 中的内容
\{\{with arg\}\}
传递过来的数据设置的新值为:\{\{.\}\}
\{\{else\}\}
传递过来的数据仍然是:\{\{.\}\}
\{\{end\}\}
包含动作
包含动作允许用户在一个模版里面包含另一个模版,从而构建嵌套的模版:
// 格式一,name为被包含的模版的名字(字符串类型)
\{\{template "模版名"\}\}
// 格式二,arg是用户想要传递给被嵌套模版的数据
\{\{template "模版名" arg\}\}
定义动作
网页中经常有很多重用的部分:导航栏、版本信息、联系方式等。这些相同的布局可以通过定义动作在模版文件中定义模版来实现。
定义模版的格式是:
\{\{define "模版名"\}\}
模版内容
\{\{end\}\}
在定义的模版中可以使用包含动作(template)来包含其他已经定义好的模版。
在html文件中定义好模版之后处理器中需要执行模版的使用就得使用ExecuteTemplate方法,其中传入定义好的模版的名字以及所要传递的数据。
在不同的模版文件中定义同名的模版文件时,需要在处理器中加载模版的时候选择指定的模版(利用一次加载多个模版来实现)。
示例:
处理器设置:
// TestTemplate 包含动作测试
func TestTemplate(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.ParseFiles("./action/template.html"))
t.Execute(w, "")
}
页面显示:
\{\{define "content"\}\}
<b>这里显示的是content模版的内容</b>
\{\{end\}\}
<div>开始显示本页面的内容</div>
\{\{template "content"\}\}
块动作
Go 1.6 引入了一个新的块动作。这个动作允许用户定义一个模版并立即使用,相当于设置了一个默认的模版。
\{\{block "模块名" .\}\}
默认显示该内容
\{\{end\}\}