Gin 系列(三):模板

Gin 系列(三):模板

一。 前言

经过上一篇文章 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
    image.png

加载模板

  • 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 中,通过 routerhandler 向模板传入参数:

    调用 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 ,观察页面内容。
    image.png

三。 模板语法

变量

变量用 {{}} 标记,. 表示当前变量,对于:

<h1>{{.msg}}</h1>

msg 变量的值 Hello Gin,最终的渲染结果为:

<h1>Hello Gin</h1>

可以通过以下方式来自定义变量

该变量名称为 msg,值为 "Hello Gin"

{{$msg := "Hello Gin"}}

在模板中直接使用 {{$msg}} 即可获取该变量内容。

函数

如果有一个 add 函数,接收两个参数 arg1arg2,实现加法功能,在模板中可以这样调用:

{{add .arg1 .arg2}}

arg1 = 1arg2 = 2 ,那么渲染结果为:

3

条件判断

模板支持 bool 类型和 string 类型的条件判断,例如:

{{if .condition}}
{{end}}

.conditiontrue 时,或者非空字符串时,条件语句才会成立。

模板还支持多分支条件:

{{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}}
    

循环

模板支持遍历 mapslice 类型的变量,关键词为 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" .}}

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://cangmang.xyz/articles/1642775284582