4.Gin HTML 模板渲染

4.Gin HTML 模板渲染

Gin HTML 模板渲染

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

创建用于渲染的模板html

a6dfe2357ab2b782d458478e280f196d.png


templates/index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>index</h1><h2>渲染的内容: {{.title}}</h2>
</body>
</html>

templates/goods.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>商品页面</h1><h2>渲染的内容: {{.title}}</h2>
</body>
</html>
路由加载模板文件

f3cedf50b2a63d5effba9d69174390f7.png

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

访问 http://localhost:8000/index

4f1a1e64f7de5654549ab67c1d8014e3.png


访问 http://localhost:8000/goods

7d3864702b1713cd252df88279a15bc5.png


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

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

创建模板文件

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

templates/admin/index.html

0780e74e29137054d5656570cb494a11.png
1695819574799
{{ define "admin/index.html" }}<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><h1>index</h1><h2>admin 渲染的内容: {{.title}}</h2></body></html>
{{end}}

templates/default/index.html

8c09fab9feee87b1b08653fba2f9a34e.png
1695819665405
{{ define "default/index.html" }}<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><h1>index</h1><h2>default 渲染的内容: {{.title}}</h2></body></html>
{{ end }}
路由加载模板文件
8b0d00fcd6c4097d95b1cbe11d17a40f.png
1695819916477
// 加载模板文件
r.LoadHTMLGlob("templates/**/*")

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

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

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

51763b84d867cb93a4eb6f7684cb1269.png
1695820021336

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

789aa541286bcf2e995d69bdd0d23da5.png
1695820038857

3. gin 模板基本语法

{{.}} 输出数据

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

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

编写结构体、以及渲染模板
38d17217f54c0d8a4d467ee11fb0bd1e.png
1695820992727
package mainimport ("fmt""github.com/gin-gonic/gin""net/http"
)// 定义结构体
type UserInfo struct {Name   stringAge    intGender string
}func main() {// 1.创建路由r := gin.Default()// 加载模板文件r.LoadHTMLGlob("templates/**/*")// 2.绑定路由规则,执行的函数// gin.Context,封装了request和response// c.HTML 渲染模板r.GET("default/index", func(c *gin.Context) {// 创建对象userInfo := UserInfo{Name:   "李白",Age:    30,Gender: "male",}// 渲染模板c.HTML(http.StatusOK, "default/index.html", gin.H{"title":    "default前台首页","userInfo": userInfo,})})// 3.监听端口,默认在8080// 监听并在 0.0.0.0:8080 上启动服务// Run("里面不指定端口号默认为8080")r.Run(":8000")
}
编写模板,使用渲染的参数
3c86854d2b95c8a47dc0e450cfe1de6f.png
1695821060579
{{ define "default/index.html" }}<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><h1>index</h1><h2>default 渲染的内容: {{.title}}</h2><h3>渲染用户信息:{{.userInfo}}</h3><span>{{.userInfo.Name}}</span><br><span>{{.userInfo.Age}}</span><br><span>{{.userInfo.Gender}}</span><br></body></html>
{{ end }}
测试如下:

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

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

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

变量

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

如下:

f18d69d3ab6c81c6b10431d7183185bb.png
1695821326461
{{/* 保存传入模板的数据   */}}
<h4>{{$obj := .title}}</h4>
<h4>模板的变量title={{$obj}}</h4>

刷新页面,测试如下:

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
{{/*  比较函数  */}}
{{ if eq .score 60}}<h4>score=60分</h4>
{{end}}
测试如下:
d75cafdabaa5f137473ded4f652fd932.png
1695821900767
条件判断

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

{{if pipeline}} T1 {{end}}
{{if pipeline}} T1 {{else}} T0 {{end}}
{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
示例如下:
{{if gt .score 60}}及格
{{else}}不及格
{{end}}
{{if gt .score 90}}优秀
{{else if gt .score 60}}及格
{{else}}不及格
{{end}}
range

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

语法:

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

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

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

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

示例如下:

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

31bb0ab16b1b6f6b064f3f7d178f880e.png
1695826297180
// c.HTML 渲染模板
r.GET("default/index", func(c *gin.Context) {// 创建对象userInfo := UserInfo{Name:   "李白",Age:    30,Gender: "male",}// 渲染模板c.HTML(http.StatusOK, "default/index.html", gin.H{"title":    "default前台首页","userInfo": userInfo,"score":    60,"hobby":    []string{"吃饭", "睡觉", "写代码"},})
})

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

35d266ffa54a460d224d501733d3e1de.png
1695826334196
{{/* 使用 range 关键字进行遍历   */}}
<h4>hobby={{.hobby}}</h4>
<ul>{{range $key,$value := .hobby}}<li>{{$value}}</li>{{else}}<li>hobby 的值其长度为 0</li>{{end}}
</ul>
测试如下:
ee3c48618a1e87accddc909cf4bf56e7.png
1695826360165
With

以前要输出数据:

<h3>渲染用户信息:</h3>
<span>{{.userInfo.Name}}</span><br>
<span>{{.userInfo.Age}}</span><br>
<span>{{.userInfo.Gender}}</span><br>

现在要输出数据:

{{with .userInfo}}<h3>with用户信息</h3><span>{{.Name}}</span><br><span>{{.Age}}</span><br><span>{{.Gender}}</span><br>
{{end}}

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

预定义函数 (了解)

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

预定义的全局函数如下:

  • and

    函数返回它的第一个 empty 参数或者最后一个参数;

    就是说"and x y"等价于"if x then y else x";所有参数都会执行;

  • or

    返回第一个非 empty 参数或者最后一个参数;

    亦即"or x y"等价于"if x then x else y";所有参数都会执行;

  • not

    返回它的单个参数的布尔值的否定

  • len

    返回它的参数的整数类型长度

  • index

    执行结果为第一个参数以剩下的参数为索引/键指向的值;

    如"index x 1 2 3"返回 x[1][2][3]的值;每个被索引的主体必须是数组、切片或者字典。

  • print

    即 fmt.Sprint

  • printf

    即 fmt.Sprintf

  • println

    即 fmt.Sprintln

  • html

    返回与其参数的文本表示形式等效的转义 HTML。

    这个函数在 html/template 中不可用。

  • urlquery

    以适合嵌入到网址查询中的形式返回其参数的文本表示的转义值。

    这个函数在 html/template 中不可用。

  • js

    返回与其参数的文本表示形式等效的转义 JavaScript。

  • call

    执行结果是调用第一个参数的返回值,该参数必须是函数类型,其余参数作为调用该函数的参数;

    如"call .X.Y 1 2"等价于 go 语言里的 dot.X.Y(1, 2);

    其中 Y 是函数类型的字段或者字典的值,或者其他类似情况;

    call 的第一个参数的执行结果必须是函数类型的值(和预定义函数如 print 明显不同);

    该函数类型值必须有 1 到 2 个返回值,如果有 2 个则后一个必须是 error 接口类型;

    如果有 2 个返回值的方法返回的 error 非 nil,模板执行会中断并返回给调用模板执行者该错误;

示例如下:
{{/* 预定义函数  */}}
<h4>title len: {{len .title}}</h4>
<h4>title hobby: {{len .hobby}}</h4>
<h4>index hobby 2: {{index .hobby 2}}</h4>

效果如下:

a9971b21bcd2c42b210a6102d670c79a.png
1695828064128
自定义模板函数

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

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

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

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

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

d4344b1fcc61b3da216b4a59e68081e0.png
1695960580888
{{/*  引入template  */}}
{{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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/156953.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【GitHub】保姆级使用教程

一、如何流畅访问GitHub 1、网易uu加速器 输入网址&#xff0c;无脑下载网易加速器&#xff1b;https://uu.163.com/ 下载安装完毕后&#xff0c;创建账号进行登录 登录后&#xff0c;在右上角搜索框中搜索“学术资源”&#xff0c;并点击&#xff1b; 稍等一会儿就会跳…

如何在3dMax中使用Python按类型选择对象?

如何在3dMax中使用Python按类型选择对象&#xff1f; 3dMax提供了pymxs API&#xff0c;这是MAXScript的Python包装器&#xff0c;可帮助您扩展和自定义3dMax&#xff0c;并更轻松地将其集成到基于Python的管道中。 pymxs模块包含一个运行时成员&#xff0c;该成员提供对MAXSc…

电子学会C/C++编程等级考试2022年09月(一级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:指定顺序输出 依次输入3个整数a、b、c,将他们以c、a、b的顺序输出。 时间限制:1000 内存限制:65536输入 一行3个整数a、b、c,以空格分隔。 0 < a,b,c < 108输出 一行3个整数c、a、b,整数之间以一个空格分隔。样例输入…

【C++进阶之路】第八篇:智能指针

文章目录 一、为什么需要智能指针&#xff1f;二、内存泄漏1.什么是内存泄漏&#xff0c;内存泄漏的危害2.内存泄漏分类&#xff08;了解&#xff09;3.如何检测内存泄漏&#xff08;了解&#xff09;4.如何避免内存泄漏 三、智能指针的使用及原理1.RAII2.智能指针的原理3.std:…

气相色谱质谱仪样品传输装置中电动针阀和微泄漏阀的解决方案

标题 摘要&#xff1a;针对目前国内外各种质谱仪压差法进样装置无法准确控制进气流量&#xff0c;且无相应配套产品的问题&#xff0c;本文提出了相应的解决方案和配套部件。解决方案主要解决了制作更小流量毛细管和毛细管进气端真空压力精密控制问题&#xff0c;微流量毛细管的…

Flutter:多线程Isolate的简单使用

在flutter中如果要使用线程&#xff0c;需要借助Isolate来实现。 简介 在Flutter中&#xff0c;Isolate是一种轻量级的线程解决方案&#xff0c;用于在应用程序中执行并发任务。Isolate可以被认为是独立于主线程的工作单元&#xff0c;它们可以在后台执行任务而不会阻塞应用程…

C++入门第八篇---STL模板---list的模拟实现

前言&#xff1a; 有了前面的string和vector两个模板的基础&#xff0c;我们接下来就来模拟实现一下list链表模板&#xff0c;我还是要强调的一点是&#xff0c;我们模拟实现模板的目的是熟练的去使用以及去学习一些对于我们本身学习C有用的知识和用法&#xff0c;而不是单纯的…

基于SpringBoot+MyBatis-Plus的校园图书管理系统

基于SpringBootMyBatis-Plus的校园图书管理系统 校园图书管理系统开发技术功能模块代码结构数据库设计运行截图源码获取 校园图书管理系统 欢迎访问此博客&#xff0c;是否为自己的毕业设计而担忧呢&#xff1f;是否感觉自己的时间不够做毕业设计呢&#xff1f;那你不妨看一下…

2023年DevOps国际峰会暨BizDevOps企业峰会(DOIS北京站)-核心PPT资料下载

一、峰会简介 在数字化转型的大背景下&#xff0c;企业选择实践 DevOps 来提升 IT 效能成为常态&#xff0c;BizDevOps 作为企业自身数字化变革的重要主题之一&#xff0c;需要全行业共同努力促进繁荣和发展。从 DevOps 到 BizDevOps&#xff0c;业务与技术如何融合&#xff1…

CentOS用nginx搭建文件下载服务器

Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器&#xff0c;而且支持热部署&#xff0c;几乎可以做到 7 * 24 小时不间断运行&#xff0c;即使运行几个月也不需要重新启动。在工作中&#xff0c;我们经常会用到需要搭建文件服务器的情况&#xff0c;这里就以在linux下搭…

不会代码也能拿高薪?掌握面试法宝,轻松10000+

快速排序&#xff08;Quicksort&#xff09;是对冒泡排序的一种改进。 快速排序由 C.A.R.Hoare 在 1962 年提出。 它的基本思想是&#xff1a;通过一趟排序将要排序的数据分割成独立的两部分&#xff0c;其中一部分的所有数据都比另外一部分的所有数据都要小&#xff0c;然后…

最新版本的橙色前端微信去水印小程序源码

好像最近去水印小程序挺火的&#xff0c;你看这就不来了一个新的去水印小程序。 橙色前端是最近比较流行的&#xff0c;很多小程序也都是这种样式&#xff0c;如果你需要其它颜色的&#xff0c;可以自己修改一下CSS即可&#xff0c;小程序云开发的&#xff0c;无需服务器。 打…

2023年11月15号期中测验判断题(Java)

本篇还有3篇相关文章-> 2023年11月15号期中测验选择题&#xff08;Java&#xff09;-CSDN博客 2023年11月15号期中测验编程题&#xff08;Java&#xff09;-CSDN博客 2023年11月15号期中测验主观题&#xff08;Java&#xff09;-CSDN博客 判断题-> T F 1-1 局…

编译器安全

在供应链安全中&#xff0c;大家一直关注采用SCA工具分析开源组件中的安全漏洞以及许可证的合规性。但是对于底层软件开发使用的编译器、链接器等安全却容易被忽视&#xff0c;其中有没有安全漏洞、有没有运行时缺陷、有没有被植入漏洞、木马等&#xff0c;似乎并没有引起多少人…

selenium判断元素是否存在的方法

文章目录 快捷方法完整示例程序 快捷方法 selenium没有exist_xxx相关的方法&#xff0c;无法直接判断元素存在。但是锁定元素时使用的browser.find_elements(By.CSS_SELECTOR, "css元素")会返回一个列表list&#xff0c;如果不存在这个元素就会返回一个空列表。因此…

【20年扬大真题】设顺序表va中的数据元素递增有序。试写一算法,将x插入到顺序表的适当位置上,以保障该表的有序性。

【20年扬大真题】 设顺序表va中的数据元素递增有序。 试写一算法&#xff0c;将x插入到顺序表的适当位置上&#xff0c;以保障该表的有序性。 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<malloc.h> #define MaxSize 9//定义最大长度 int InitAr…

第4章 向量、SIMD和GPU体系结构中的数据级并行

4.1 引言 有多少应用程序拥有大量的数据级并行DLP&#xff1f;SIMD分类Flyn被提出后5年。答案不仅包括科学运算中的矩阵运算&#xff0c;还包括面向多媒体的图像和声音处理以及机器学习算法。 由于SIMD可以执行多个数据操作&#xff0c;能效比MIMD要高&#xff0c;使得SIMD对…

Day37力扣打卡

打卡记录 美化数组的最少删除数&#xff08;贪心&#xff09; 链接 class Solution:def minDeletion(self, nums: List[int]) -> int:n, cnt len(nums), 0for i in range(n):if (i - cnt) % 2 0 and i 1 < n and nums[i] nums[i 1]:cnt 1return cnt 1 if (n - c…

x shell 用作串口调试助手

x shell 用作串口调试助手 Xshell 介绍 是一个强大的安全终端模拟软件&#xff0c;它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议。Xshell 通过互联网到远程主机的安全连接以及它创新性的设计和特色帮助用户在复杂的网络环境中享受他们的工作。 Xshell可以在Wi…

【Java】异常处理及其语法、抛出异常、自定义异常(完结)

&#x1f33a;个人主页&#xff1a;Dawn黎明开始 &#x1f380;系列专栏&#xff1a;Java ⭐每日一句&#xff1a;道阻且长&#xff0c;行则将至 &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️ 文章目录 一.&#x1f510;异…