Gin框架官方文档详解03:HTML渲染

官方文档:https://gin-gonic.com/zh-cn/docs/

注:强烈建议没用过Gin的读者先阅读第一节:第一个Gin应用

目录

一、简单渲染

以"03HTML渲染"为根目录,创建如下目录结构:

bash 复制代码
├─demo01
│  │  main.go
│  └─templates
│          index.html
├─demo02
│  │  main.go
│  └─templates
│      ├─posts
│      │      index.html
│      └─users
│              index.html
├─demo03
│      file1.html
│      file2.html
│      main.go
├─demo04
│  │  main.go
│  └─templates
│          index.html
└─demo05
    │  main.go
    └─templates
            raw.html

进入到demo01,填充代码:

main.go

go 复制代码
package main

import (
	"net/http" // 导入 HTTP 状态码和服务功能

	"github.com/gin-gonic/gin" // 导入 Gin 框架
)

func main() {
	router := gin.Default() // 创建一个默认的 Gin 路由器,带有默认的中间件(如日志和恢复)

	// 加载所有位于 /templates 目录下的 HTML 文件,支持通配符(如 *.html)
	router.LoadHTMLGlob("templates/*")
	// 使用 LoadHTMLFiles 可以加载指定的多个文件
	// router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")

	// 设置一个 GET 路由,当用户访问 /index 时,返回 HTML 页面
	router.GET("/index", func(c *gin.Context) {
		// 使用 HTML 渲染函数,HTTP 状态码 200 (http.StatusOK),
		// 渲染 "index.html" 文件,并传递数据(键值对形式)供模板使用
		c.HTML(http.StatusOK, "index.html", gin.H{
			"title": "Main website", // 传递 "title" 变量到模板
		})
	})

	// 运行应用程序,并监听在端口 8080 上
	router.Run(":8080")
}

index.html

html 复制代码
<html>
<h1>
    {{ .title }} <!-- 这里是模板占位符,将被渲染时替换为 title 变量的值 -->
</h1>

</html>

LoadHTMLGlob():用于加载模板文件的函数。LoadHTMLGlob("../templates/*") 表示加载 .../templates 目录下的所有 HTML 文件。它支持通配符,常用于一次性加载多个模板。
LoadHTMLFiles():和 LoadHTMLGlob() 类似,但它不使用通配符,而是明确列出要加载的模板文件。可以根据需要使用该函数加载特定的模板文件。
c.HTML(http.StatusOK, "index.html", gin.H{"title": "Main website"}):渲染 index.html 模板,并将 title 变量传递给模板,值为 "Main website"。在模板文件中,{``{ .title }} 会被渲染为传递进来的 title 值。
注意 :Gin 的模板引擎支持多种文件扩展名,常见的 .html 文件扩展名并不是必须的,比如你可以将模板文件命名为 .tmpl,模板引擎同样能够识别和渲染这些文件。但个人建议仍使用.html,因为IDE都能对.html提供代码高亮和补全。
效果

二、使用不同目录下名称相同的模板

进入到demo02,填充代码:

main.go

go 复制代码
package main

import (
	"net/http" // 导入 HTTP 状态码和服务功能

	"github.com/gin-gonic/gin" // 导入 Gin 框架
)

func main() {
	router := gin.Default() // 创建一个默认的 Gin 路由器,带有默认中间件(如日志和恢复)

	// 加载 templates 目录下所有子目录的所有模板文件
	router.LoadHTMLGlob("templates/**/*")

	// 定义一个 GET 路由,处理 /posts/index
	router.GET("/posts/index", func(c *gin.Context) {
		// 渲染 posts/index.html 模板,并传递数据
		c.HTML(http.StatusOK, "posts/index.html", gin.H{
			"title": "Posts", // 传递标题
		})
	})

	// 定义另一个 GET 路由,处理 /users/index
	router.GET("/users/index", func(c *gin.Context) {
		// 渲染 users/index.html 模板,并传递数据
		c.HTML(http.StatusOK, "users/index.html", gin.H{
			"title": "Users", // 传递标题
		})
	})

	// 启动 HTTP 服务器,监听 8080 端口
	router.Run(":8080")
}

posts/index.html

html 复制代码
{{ define "posts/index.html" }} <!-- 定义一个名为 "posts/index.html" 的模板块 -->
<html>
<h1>
    {{ .title }} <!-- 这里会被传递进来的标题替换 -->
</h1>
<p>Using posts/index.html</p> <!-- 说明当前使用的是哪个模板 -->

</html>
{{ end }} <!-- 结束模板块定义 -->

users/index.html

html 复制代码
{{ define "users/index.html" }} <!-- 定义一个名为 "users/index.html" 的模板块 -->
<html>
<h1>
    {{ .title }} <!-- 这里会被传递进来的标题替换 -->
</h1>
<p>Using users/index.html</p> <!-- 说明当前使用的是哪个模板 -->

</html>
{{ end }} <!-- 结束模板块定义 -->

模板定义:每个模板都使用 {``{ define "模板名称" }}{``{ end }} 包裹,定义了一个可重用的模板块。在渲染时,通过指定模板的完整名称来选择要渲染的具体模板。

使得在不同目录中存在同名模板时(比如这里都有index.html) ,可以准确指定使用哪个模板。当然,使用LoadHTMLFiles()可以不用定义模板块,也能达到相同的效果,就是要指定具体文件路径而已。相对来说,LoadHTMLGlob()使用更方便,不管templates下有多少个模板,调用语句都是一样的。
效果

三、自定义模板渲染器

进入到demo03,填充代码:

main.go

go 复制代码
package main

import (
	"html/template" // 导入 HTML 模板包
	"net/http"

	"github.com/gin-gonic/gin" // 导入 Gin 框架
)

func main() {
	router := gin.Default()

	// 加载 file1.html 和 file2.html 模板文件
	html := template.Must(template.ParseFiles("file1.html", "file2.html"))
	// 设置自定义的 HTML 模板渲染器
	router.SetHTMLTemplate(html)

	// 定义一个路由,当用户访问 /file1 时,返回 file1.html 页面
	router.GET("/file1", func(c *gin.Context) {
		c.HTML(http.StatusOK, "file1.html", gin.H{
			"title": "Hello, World", // 传递 "title" 变量到模板
		})
	})

	// 定义另一个路由,当用户访问 /file2 时,返回 file2.html 页面
	router.GET("/file2", func(c *gin.Context) {
		c.HTML(http.StatusOK, "file2.html", gin.H{
			"title": "Hello, World", // 传递 "title" 变量到模板
		})
	})

	// 启动 Gin 服务器,监听在 8080 端口
	router.Run(":8080")
}

file1.html

html 复制代码
<!DOCTYPE html>
<html>

<head>
    <title>{{ .title }} - File 1</title>
</head>

<body>
    <h1>{{ .title }} from File 1</h1>
    <p>This content is rendered from file1.html.</p>
</body>

</html>

file2.html

html 复制代码
<!DOCTYPE html>
<html>

<head>
    <title>{{ .title }} - File 2</title>
</head>

<body>
    <h1>{{ .title }} from File 2</h1>
    <p>This content is rendered from file2.html.</p>
</body>

</html>

效果

到目前为止,我们已经学了三种模板加载方法:

1.定义模板名,用LoadHTMLGlob()

2.不定义模板名,用LoadHTMLFiles()

3.不用模板目录,用template.Must()

在真实开发中,团队和项目的性质通常会影响选择的方式。常见的倾向包括:

中大型项目:往往会选择 1,因为它能保持项目结构的整洁,并且方便管理多个模板。

小型项目:可能会倾向于 2,因为它提供了更大的灵活性和可控性。

原型开发或快速迭代:通常会选择 3,以便于快速验证和调整。

四、自定义分隔符

进入到demo04,填充代码:

main.go

go 复制代码
package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	// 设置自定义的分隔符
	r.Delims("{[{", "}]}")

	// 加载指定路径下的 HTML 模板
	r.LoadHTMLGlob("templates/*")

	// 定义一个路由,当用户访问 /index 时,返回 index.html 页面
	r.GET("/index", func(c *gin.Context) {
		c.HTML(http.StatusOK, "index.html", gin.H{
			"title": "Custom Delimiter Example", // 传递 "title" 变量到模板
		})
	})

	// 启动 Gin 服务器,监听在 8080 端口
	r.Run(":8080")
}

index.html

html 复制代码
<!DOCTYPE html>
<html>

<head>
    <title>{[{ .title }]}</title>
</head>

<body>
    <h1>{[{ .title }]}</h1>
    <p>Welcome to the page with custom delimiters!</p>
</body>

</html>

效果

五、自定义模板函数

进入到demo05,填充代码:

main.go

go 复制代码
package main

import (
	"fmt"
	"html/template"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
)

// 自定义函数:将时间格式化为指定格式
func formatAsDate(t time.Time) string {
	year, month, day := t.Date()
	return fmt.Sprintf("%d/%02d/%02d", year, month, day)
}

func main() {
	router := gin.Default()
	router.Delims("{[{", "}]}") // 设置自定义分隔符

	// 注册自定义函数
	router.SetFuncMap(template.FuncMap{
		"formatAsDate": formatAsDate, // 将 formatAsDate 函数注册为模板函数
	})

	// 加载 HTML 模板文件
	router.LoadHTMLFiles("templates/raw.html")

	// 定义路由,当用户访问 /raw 时,返回 raw.html 模板
	router.GET("/raw", func(c *gin.Context) {
		c.HTML(http.StatusOK, "raw.html", map[string]interface{}{
			"now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC), // 传递当前时间到模板
		})
	})

	// 启动 Gin 服务器,监听在 8080 端口
	router.Run(":8080")
}

raw.html

html 复制代码
Date: {[{.now | formatAsDate}]}

注意

1.FuncMap()中的key和value可以不同。

2.html中调用的函数名是FuncMap()中的key ,不是value!也就是说,value的值可以随便取,不影响html调用。

3.SetFuncMap必须在 LoadHTMLFiles之前调用!
效果

六、总结

在使用 Gin 框架进行 HTML 渲染时,可以通过 LoadHTMLGlob() 或 LoadHTMLFiles() 方法加载模板文件。LoadHTMLGlob() 支持使用通配符,适合批量加载多个模板,而 LoadHTMLFiles() 允许精确加载特定的模板文件。通过在模板中定义结构,可以避免不同目录中同名模板的冲突,确保在渲染时通过完整名称来选择正确的模板。自定义模板渲染器和函数映射(使用 SetFuncMap)可以扩展模板功能,如格式化日期。使用自定义分隔符可改变模板中变量的标识符。

相关推荐
风尚云网27 分钟前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
佚先森1 小时前
2024ARM网络验证 支持一键云注入引流弹窗注册机 一键脱壳APP加固搭建程序源码及教程
java·html
Myli_ing2 小时前
HTML的自动定义倒计时,这个配色存一下
前端·javascript·html
ifanatic2 小时前
[面试]-golang基础面试题总结
面试·职场和发展·golang
懒是一种态度2 小时前
Golang 调用 mongodb 的函数
数据库·mongodb·golang
XINGTECODE3 小时前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
入 梦皆星河3 小时前
在 Ubuntu/Debian 上安装 Go
ubuntu·golang·debian
FØund4043 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
一棵开花的树,枝芽无限靠近你3 小时前
【PPTist】添加PPT模版
前端·学习·编辑器·html
凡人的AI工具箱3 小时前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang