[!NOTE]
- 项目启用视图在
routes/file.go
- 模板文件定义在
templates
目录 - 基于go1.16之后
embed
特性,我们打包的时候会把模板文件也一起打包
设置模板目录
func fileRoute(r *gin.Engine) {
f := global.FS
templ := template.Must(template.New("").Funcs(Funcs).ParseFS(f, "templates/*/*"))
r.SetHTMLTemplate(templ)
// example: /public/static/js/a.js
r.StaticFS("/public", http.FS(f))
}
在控制器输出视图
[!NOTE] 定义控制器
func PostController(c *gin.Context) {
tool.HTML(c, "posts/index.tmpl", tool.M{"title":"posts"})
}
[!NOTE] 定义路由
router.GET("/posts/index", controller.PostController)
[!NOTE] 定义模板
因为排版原因
{ }
替换成{
{
}
}
{define "posts/index.tmpl"}
<html><h1>
{.title}
</h1>
<p>Using posts/index.tmpl</p>
</html>
end
模板嵌套
[!NOTE] 定义模板1
{ define "common/header" }
<h1>
Using header
</h1>
{ end }
[!NOTE] 定义模板2
{ define "posts/index.tmpl" }
{template "common/header" .}
<html><h1>
{ .title }
</h1>
<p>Using posts/index.tmpl</p>
</html>
{ end }
模板用法
[!NOTE] define
{ define "name" } T { end }
[!NOTE] template
第一种是直接执行名为name的模板,模板的全局数据对象.设置为nil。第二种是点.设置为title的值,并执行名为name的模板。
{ template "name" }
{ template "name" .title }
[!NOTE] block 的语义是如果有命名为 name 的模板,就引用过来执行,如果没有命名为 name 的模板,就是执行自己定义的内容。换句话说,block可以认为是设置一个默认模板
{ block "name" pipeline } T1 { end }
[!NOTE] with 创建一个新的上下文环境,在此环境中的 . 与外面的 . 无关。 对于第一种格式,当pipeline不为0值的时候,点.设置为pipeline运算的值,否则跳过。对于第二种格式,当pipeline为0值时,执行else语句块,否则.设置为pipeline运算的值,并执行T1。
{ with pipeline } T1 { end }
// 如果 pipeline 是空值则输出 T0
{ with pipeline } T1 { else } T0 { end }
{ with arg }
. // 此时 . 就是 arg
{ end }
[!NOTE] 输出变量
{ .title }
[!NOTE] 条件语句
{ if pipeline } T1 { end }
{ if pipeline } T1 { else } T0 { end }
{ if pipeline } T1 { else if pipeline } T0 { end }
// 上面的语法其实是下面的简写
{ if pipeline } T1 { else }{ if pipeline } T0 { {end }{ end }
{ if pipeline } T1 { else if pipeline } T2 { else } T0 { end }
[!NOTE] 循环语句
{ range pipeline } T1 { end }
// 这个 else 比较有意思,如果 pipeline 的长度为 0 则输出 else 中的内容
{ range pipeline } T1 { else } T0 { end }
// 获取容器的下标
{ range $index, $value := pipeline } T1 { end }
模板方法
[!NOTE] 字段
{.} 表示当前字段
{.Name} 表示某个结构体的 Name 字段
结构体字段需能被外部访问:即 字段首字母大写
[!NOTE] 自定义方法 在
routes/file.go
定义参考DefaultValueFunc
同时添加到Funcs[!NOTE] 内置函数 call 执行方法 ,返回参数必须是1个或2个,
{ call call .funtion .param}
[!NOTE] not 非
{if not .condition}
{end}
[!NOTE] and 与
{if and .condition1 .condition2}
{end}
[!NOTE] or 或
{if or .condition1 .condition2}
{end}
[!NOTE] eq 判断相等
{if eq .content1 .content2}
{end}
[!NOTE] ne 不等于
{if ne .var1 .var2}
{end}
[!NOTE] lt 小于
{if lt .var1 .var2}
{end}
[!NOTE] le 小于等于
{if le .var1 .var2}
{end}
[!NOTE] gt 大于
{if gt .var1 .var2}
{end}
[!NOTE] ge 大于等于
{if ge .var1 .var2}
{end}
[!NOTE] 打印
{"你好"|print "世界"} // fmt.Sprint 的别名
{"你好"|printf "%d %s" 123} // Spintf的别名
{"你好"|println "世界"} // Println
[!NOTE] len 长度
{"hello"|len} // 返回参数的长度
[!NOTE] html转义
{ "<br>"|html} // 转义文本中html的标签
[!NOTE] 返回用js的escape处理后的文本, 自动进行html转义
{ "?a=123&b="你好"|js}
[!NOTE] urlquery url编码
{?q=关键字&p=1|urlquery} // 进行url编码