
一。 前言
经过上一篇文章 Gin 系列(二):路由 的学习,我们了解了 Gin 中路由的基本使用。接下来将会介绍如何在 Gin 中配置和使用模板。
二。 配置模板
添加模板
-
在项目目录中创建
template文件夹,同时在template目录下创建一个index.tmpl文件,写入以下内容:<!DOCTYPE html> <html lang="zh-cmn-Hans"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>首页</title> </head> <body> <h1>{{.msg}}</h1> </body> </html> -
默认在
Goland中,.tmpl类型文件没有语法高亮,我们可以点击File -> Settings -> Editor -> File Types,找到Go Templates,将.tmpl标注为Go Templates。

加载模板
-
在
main.go中利用LoadHTMLGlob方法加载template目录下的模板:LoadHTMLGlob可以一次性加载目录下所有的模板文件,但LoadHTMLFiles只能加载一个模板文件,在这里我们使LoadHTMLGlob。package main import ( "github.com/gin-gonic/gin" "log" ) func main() { router := gin.Default() // 加载模板 router.LoadHTMLGlob("template/*") err := router.Run(":8080") if err != nil { log.Panicln("error: ", err.Error()) } }
测试模板
-
在
main.go中,通过router和handler向模板传入参数:调用
gin.Context中的HTML方法,渲染模板和参数,HTML方法有三个参数,第一个为状态码,第二个模板文件路径,第三个为变量。package main import ( "github.com/gin-gonic/gin" "log" "net/http" ) func main() { router := gin.Default() // 加载模板 router.LoadHTMLGlob("template/*") // 测试模板 router.GET("", func(c *gin.Context) { c.HTML(http.StatusOK, "index.tmpl", gin.H{ "msg": "Hello Gin", }) }) err := router.Run(":8080") if err != nil { log.Panicln("error: ", err.Error()) } } -
运行项目,在浏览器中访问 http://localhost:8080 ,观察页面内容。

三。 模板语法
变量
变量用 {{}} 标记,. 表示当前变量,对于:
<h1>{{.msg}}</h1>
若 msg 变量的值 Hello Gin,最终的渲染结果为:
<h1>Hello Gin</h1>
可以通过以下方式来自定义变量:
该变量名称为
msg,值为"Hello Gin"。
{{$msg := "Hello Gin"}}
在模板中直接使用 {{$msg}} 即可获取该变量内容。
函数
如果有一个 add 函数,接收两个参数 arg1 和 arg2,实现加法功能,在模板中可以这样调用:
{{add .arg1 .arg2}}
若 arg1 = 1,arg2 = 2 ,那么渲染结果为:
3
条件判断
模板支持 bool 类型和 string 类型的条件判断,例如:
{{if .condition}}
{{end}}
当 .condition 为 true 时,或者非空字符串时,条件语句才会成立。
模板还支持多分支条件:
{{if .conditon1}}
{{else if .condition2}}
{{end}}
模板中常见的条件判断函数有:
- not 非
{{if not .condition}} {{end}} - and 与
{{if .condition1 and .condition2}} {{end}} - or 或
{{if .condition1 or .condition2}} {{end}} - eq 等于
{{if eq .arg1 .arg2}} {{end}} - ne 不等于
{{if ne .arg1 .arg2}} {{end}} - lt 小于
{{if lt .arg1 .arg2}} {{end}} - le 小于等于
{{if le .arg1 .arg2}} {{end}} - gt 大于
{{if gt .arg1 .arg2}} {{end}} - ge 大于等于
{{if ge .arg1 .arg2}} {{end}}
循环
模板支持遍历 map 和 slice 类型的变量,关键词为 range:
在循环体内部,通过
$i和$v来访问键和值。
{{range $i, $v := .list}}
{{$i}} : {{$v}}
{{end}}
若要在循环体内部访问外部的变量,可以通过 $. 来访问:
{{range $i, $v := .list}}
{{$.msg}}
{{end}}
父子模板
在设计模板页面的时候,可以对一些公共内容进行整理,比如全局样式、全局脚本、全局导航栏等,将其定义成子模板,然后在父模板中引入,以减少代码量。
可以通过 define 关键词定义模板:
{{define "css"}}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.css">
{{end}}
在父模板中以 template 关键词引入刚刚定义的子模板 "css":
{{template "css"}}
可以通过在引入模板最后添加 . 让子模板获得父模板的变量:
{{template "css" .}}