• 4.Gin HTML 模板渲染


    4.Gin HTML 模板渲染

    Gin HTML 模板渲染

    1. 全部模板放在一个目录里面的配置方法

    创建用于渲染的模板html

    a6dfe2357ab2b782d458478e280f196d.png


    templates/index.html

    1. "en">
    2.     "UTF-8">
    3.     Title
    4.     

      index

    5.     

      渲染的内容: {{.title}}

    templates/goods.html

    1. "en">
    2.     "UTF-8">
    3.     Title
    4.     

      商品页面

    5.     

      渲染的内容: {{.title}}

    路由加载模板文件

    f3cedf50b2a63d5effba9d69174390f7.png

    1. // 加载模板文件
    2. r.LoadHTMLGlob("templates/*")
    渲染模板
    1. // c.HTML 渲染模板
    2. r.GET("/index"func(c *gin.Context) {
    3.     c.HTML(http.StatusOK, "index.html", gin.H{"title""前台首页"})
    4. })
    5. r.GET("/goods"func(c *gin.Context) {
    6.     c.HTML(http.StatusOK, "goods.html", gin.H{"title""商品页面"})
    7. })
    测试如下

    访问 http://localhost:8000/index

    4f1a1e64f7de5654549ab67c1d8014e3.png


    访问 http://localhost:8000/goods

    7d3864702b1713cd252df88279a15bc5.png


    2. 模板放在不同目录里面的配置方法

    Gin 框架中如果不同目录下面有同名模板的话, 我们需要使用下面方法加载模板

    创建模板文件

    注意:定义模板的时候需要通过 define 定义名称

    templates/admin/index.html

    0780e74e29137054d5656570cb494a11.png
    1695819574799
    1. {{ define "admin/index.html" }}
    2.     
    3.     "en">
    4.     
    5.         "UTF-8">
    6.         Title
    7.     
    8.     
    9.     

      index

    10.     

      admin 渲染的内容: {{.title}}

    11.     
    12.     
    13. {{end}}

    templates/default/index.html

    8c09fab9feee87b1b08653fba2f9a34e.png
    1695819665405
    1. {{ define "default/index.html" }}
    2.     
    3.     "en">
    4.     
    5.         "UTF-8">
    6.         Title
    7.     
    8.     
    9.     

      index

    10.     

      default 渲染的内容: {{.title}}

    11.     
    12.     
    13. {{ end }}
    路由加载模板文件
    8b0d00fcd6c4097d95b1cbe11d17a40f.png
    1695819916477
    1. // 加载模板文件
    2. r.LoadHTMLGlob("templates/**/*")

    **表示为文件夹路径, **/* 表示为所有文件夹下的所有文件

    渲染模板
    246116a647e239595ceb484d3615ae1f.png
    1695819990290
    1. // c.HTML 渲染模板
    2. r.GET("default/index"func(c *gin.Context) {
    3.     c.HTML(http.StatusOK, "default/index.html", gin.H{"title""default前台首页"})
    4. })
    5. r.GET("admin/index"func(c *gin.Context) {
    6.     c.HTML(http.StatusOK, "admin/index.html", gin.H{"title""admin前台首页"})
    7. })
    8. r.GET("admin/goods"func(c *gin.Context) {
    9.     c.HTML(http.StatusOK, "admin/goods.html", gin.H{"title""商品页面"})
    10. })
    测试如下

    访问 http://localhost:8000/default/index

    51763b84d867cb93a4eb6f7684cb1269.png
    1695820021336

    访问 http://localhost:8000/admin/index

    789aa541286bcf2e995d69bdd0d23da5.png
    1695820038857

    3. gin 模板基本语法

    {{.}} 输出数据

    模板语法都包含在{{和}}中间,其中{{.}}中的点表示当前对象。

    当我们传入一个结构体对象时,我们可以根据.来访问结构体的对应字段。例如:

    编写结构体、以及渲染模板
    38d17217f54c0d8a4d467ee11fb0bd1e.png
    1695820992727
    1. package main
    2. import (
    3.     "fmt"
    4.     "github.com/gin-gonic/gin"
    5.     "net/http"
    6. )
    7. // 定义结构体
    8. type UserInfo struct {
    9.     Name   string
    10.     Age    int
    11.     Gender string
    12. }
    13. func main() {
    14.     // 1.创建路由
    15.     r := gin.Default()
    16.     // 加载模板文件
    17.     r.LoadHTMLGlob("templates/**/*")
    18.     // 2.绑定路由规则,执行的函数
    19.     // gin.Context,封装了request和response
    20.     // c.HTML 渲染模板
    21.     r.GET("default/index"func(c *gin.Context) {
    22.        // 创建对象
    23.        userInfo := UserInfo{
    24.           Name:   "李白",
    25.           Age:    30,
    26.           Gender: "male",
    27.        }
    28.        // 渲染模板
    29.        c.HTML(http.StatusOK, "default/index.html", gin.H{
    30.           "title":    "default前台首页",
    31.           "userInfo": userInfo,
    32.        })
    33.     })
    34.     // 3.监听端口,默认在8080
    35.     // 监听并在 0.0.0.0:8080 上启动服务
    36.     // Run("里面不指定端口号默认为8080")
    37.     r.Run(":8000")
    38. }
    编写模板,使用渲染的参数
    3c86854d2b95c8a47dc0e450cfe1de6f.png
    1695821060579
    1. {{ define "default/index.html" }}
    2.     
    3.     "en">
    4.     
    5.         "UTF-8">
    6.         Title
    7.     
    8.     
    9.     

      index

    10.     

      default 渲染的内容: {{.title}}

    11.     

      渲染用户信息:{{.userInfo}}

    12.     {{.userInfo.Name}}
    13.     {{.userInfo.Age}}
    14.     {{.userInfo.Gender}}
    15.     
    16.     
    17. {{ end }}
    测试如下:

    访问 http://localhost:8000/default/index

    e93cb09ead4359b0c9102e37d9a389db.png
    1695821107785
    模板的注释
    b23b3d356a64e241dd2a8e5123cd3268.png
    1695821176846
    {{/* 模板的注释  */}}

    注释,执行时会忽略。可以多行。注释不能嵌套,并且必须紧贴分界符始止。

    变量

    我们还可以在模板中声明变量,用来保存传入模板的数据或其他语句生成的结果。具体语法

    如下:

    f18d69d3ab6c81c6b10431d7183185bb.png
    1695821326461
    1. {{/* 保存传入模板的数据   */}}
    2. {{$obj := .title}}

    3. 模板的变量title={{$obj}}

    刷新页面,测试如下:

    6953d86434681b3445fd744545e17d48.png
    1695821384861
    移除空格

    有时候我们在使用模板语法的时候会不可避免的引入一下空格或者换行符,这样模板最终渲染出来的内容可能就和我们想的不一样,这个时候可以使用{{-语法去除模板内容左侧的所有空白符号, 使用-}}去除模板内容右侧的所空白符号。

    例如:

    f835bc7dd7ef199b35025076b1d6685a.png
    1695821566124
    {{-        .userInfo.Name     -}}

    测试效果如下:

    71eca416fa4e6cb1a47bdc9b652a1d40.png
    1695821611978

    注意:-要紧挨{{和}},同时与模板值之间需要使用空格分隔。

    比较函数

    布尔函数会将任何类型的零值视为假,其余视为真。

    下面是定义为函数的二元比较运算的集合:

    eq 如果 arg1 == arg2 则返回真

    ne 如果 arg1 != arg2 则返回真

    lt 如果 arg1 < arg2 则返回真

    le 如果 arg1 <= arg2 则返回真

    gt 如果 arg1 > arg2 则返回真

    ge 如果 arg1 >= arg2 则返回真

    示例如下:
    b2a3f8393f4b8b9f6086c38eb0a67234.png
    1695821869829
    1. {{/*  比较函数  */}}
    2. {{ if eq .score 60}}
    3.     

      score=60

    4. {{end}}
    测试如下:
    d75cafdabaa5f137473ded4f652fd932.png
    1695821900767
    条件判断

    Go 模板语法中的条件判断有以下几种:

    1. {{if pipeline}} T1 {{end}}
    2. {{if pipeline}} T1 {{else}} T0 {{end}}
    3. {{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
    示例如下:
    1. {{if gt .score 60}}
    2.     及格
    3. {{else}}
    4.     不及格
    5. {{end}}
    1. {{if gt .score 90}}
    2.     优秀
    3. {{else if gt .score 60}}
    4.     及格
    5. {{else}}
    6.     不及格
    7. {{end}}
    range

    Go 的模板语法中使用 range 关键字进行遍历,有以下两种写法,其中 传递 的值必须是数组、切片、字典或者通道。

    语法:

    1. {{range $key,$value := .obj}}
    2.  {{$value}}
    3. {{end}}

    如果 传递 的值其长度为 0,不会有任何输出

    1. {{range $key,$value := .obj}}
    2.  {{$value}}
    3. {{else}}
    4.  pipeline 的值其长度为 0
    5. {{end}}

    如果 pipeline 的值其长度为 0,则会执行 else 分支。

    示例如下:

    首先往模板传递一个数组:

    31bb0ab16b1b6f6b064f3f7d178f880e.png
    1695826297180
    1. // c.HTML 渲染模板
    2. r.GET("default/index"func(c *gin.Context) {
    3.     // 创建对象
    4.     userInfo := UserInfo{
    5.        Name:   "李白",
    6.        Age:    30,
    7.        Gender: "male",
    8.     }
    9.     // 渲染模板
    10.     c.HTML(http.StatusOK, "default/index.html", gin.H{
    11.        "title":    "default前台首页",
    12.        "userInfo": userInfo,
    13.        "score":    60,
    14.        "hobby":    []string{"吃饭""睡觉""写代码"},
    15.     })
    16. })

    在模板使用 range 渲染 hobby 参数:

    35d266ffa54a460d224d501733d3e1de.png
    1695826334196
    1. {{/* 使用 range 关键字进行遍历   */}}
    2. hobby={{.hobby}}

      •     {{range $key,$value := .hobby}}
      •         
      • {{$value}}
    3.     {{else}}
    4.         
    5. hobby 的值其长度为 0
  •     {{end}}
  • 测试如下:
    ee3c48618a1e87accddc909cf4bf56e7.png
    1695826360165
    With

    以前要输出数据:

    1. 渲染用户信息:

    2. {{.userInfo.Name}}
    3. {{.userInfo.Age}}
    4. {{.userInfo.Gender}}

    现在要输出数据:

    1. {{with .userInfo}}
    2.     

      with用户信息

    3.     {{.Name}}
    4.     {{.Age}}
    5.     {{.Gender}}
    6. {{end}}

    简单理解:相当于 var :=.user

    预定义函数 (了解)

    执行模板时,函数从两个函数字典中查找:首先是模板函数字典,然后是全局函数字典。一般不在模板内定义函数,而是使用 Funcs 方法添加函数到模板里。

    预定义的全局函数如下:

    示例如下:
    1. {{/* 预定义函数  */}}
    2. title len: {{len .title}}

    3. title hobby: {{len .hobby}}

    4. index hobby 2: {{index .hobby 2}}

    效果如下:

    a9971b21bcd2c42b210a6102d670c79a.png
    1695828064128
    自定义模板函数

    我们经常有需要将时间转换格式的情况,下面我们使用自定义模板函数来演示。

    定义时间转换格式函数
    02a090aebb8df6980e502b4709c7454b.png
    1695828577887
    1. // 定义时间格式转换的方法
    2. func formatAsDate(t time.Time) string {
    3.     year, month, day := t.Date()
    4.     return fmt.Sprintf("%d/%02d/%02d", year, month, day)
    5. }
    6. func main() {
    7.     // 1.创建路由
    8.     r := gin.Default()
    9.     //注册全局模板函数 注意顺序,注册模板函数需要在加载模板上面
    10.     r.SetFuncMap(template.FuncMap{"formatDate": formatAsDate})
    11.     // 加载模板文件
    12.     r.LoadHTMLGlob("templates/**/*")
    13.     
    14. }
    传递时间参数到模板
    64be331f7abca71612432d90e2a3ee14.png
    1695828631467
    1. // c.HTML 渲染模板
    2. r.GET("default/index"func(c *gin.Context) {
    3.     // 创建对象
    4.     userInfo := UserInfo{
    5.        Name:   "李白",
    6.        Age:    30,
    7.        Gender: "male",
    8.     }
    9.     // 渲染模板
    10.     c.HTML(http.StatusOK, "default/index.html", gin.H{
    11.        "title":    "default前台首页",
    12.        "userInfo": userInfo,
    13.        "score":    60,
    14.        "hobby":    []string{"吃饭""睡觉""写代码"},
    15.        "now":      time.Now(),
    16.     })
    17. })
    在模板使用自定义函数
    8b135e08358500c62cf74ec3c38945a5.png
    1695828664347
    1. {{/* 自定义函数   */}}
    2. 自定义时间转换函数: 

    3. {{.now | formatDate}} 
    4. 或者
    5. {{formatDate .now }} 
    效果如下
    5ba2cb131e354e3de3d41da6039c7acb.png
    1695828686465
    传递多个参数到自定义参数

    在上面只传递了一个参数,如果需要传递多个参数,示例如下:

    定义模板函数
    9c990a715b5eb3a900ebef2178995b33.png
    1695958515629
    1. // 定义打印信息的方法
    2. func printlnMsg(str1 string, str2 string) string {
    3.     return fmt.Sprintf("%s.....%s", str1, str2)
    4. }
    1. //注册全局模板函数 注意顺序,注册模板函数需要在加载模板上面
    2. r.SetFuncMap(template.FuncMap{
    3.     "formatDate": formatAsDate,
    4.     "printlnMsg": printlnMsg,
    5. })
    传递两个字符串到模板
    29bf7972e360c9e6b47e5dd570eeedb0.png
    1695959125016
    在模板中使用自定义函数
    d9894ff3db77857a010232241b3699e8.png
    1695959192909
    1. {{/* 传入多个函数到自定义函数 */}}
    2. {{printlnMsg .str1 .str2}}
    效果如下
    1ee93200b27f66a95cb02b84ce0aa869.png
    1695959223832
    嵌套 template
    新建 templates/public/page_head.html
    0511dd8ad849a394c96d5facc8607f13.png
    1695960430181
    1. {{ define "public/page_head.html" }}
    2.     "background-color: black; color: aliceblue">这一个公共的标题, title={{.title}}
    3. {{end}}
    引入 template

    分别在 admin/index.html  和 default/index.html 的顶部引入 page_head

    d4344b1fcc61b3da216b4a59e68081e0.png
    1695960580888
    1. {{/*  引入template  */}}
    2. {{template "public/page_head.html" .}}

    1、引入的名字为 page_head.html 中定义的名字

    2、引入的时候注意最后的点.,表示传入该页面的参数

    测试效果

    访问 http://localhost:8000/admin/index

    705b9c45a169d39f686e97715716e953.png
    1695960664016

    访问 http://localhost:8000/default/index

    f29d85e0acbbc2030989f7f4af9af972.png
    1695960688670
  • 相关阅读:
    在组件中使用store中的成员
    【SQLServer】并行的保留线程和已使用线程
    Flutter 开发者工具 Android Studio 开发Flutter应用
    Redis分布式锁
    别看了,这就是你的题呀(二)
    PHP乱七八糟面试题
    TCP连接保活机制
    海格里斯HEGERLS仓储货架厂家标准解析|智能自动化立体仓库AS/RS存储系统
    java 时间相减并转化为天的十进制
    “一个优秀程序员可抵五个普通程序员!”
  • 原文地址:https://blog.csdn.net/u012887259/article/details/134522363