一。 前言
经过上一篇文章 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" .}}