欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > gin框架 HTML 模板加载,渲染 使用详解和总结

gin框架 HTML 模板加载,渲染 使用详解和总结

2025/5/10 10:57:24 来源:https://blog.csdn.net/tekin_cn/article/details/140046795  浏览:    关键词:gin框架 HTML 模板加载,渲染 使用详解和总结

gin框架中默认的HTML模板渲染使用  LoadHTMLGlob() 或者 LoadHTMLFiles() , 这个地方如果是使用的LoadHTMLGlob() 这个方法的话是有坑的,即当你的模板文件放在不同的文件夹中时,使用这个方式加载会将文件夹也作为文件加载进去,从而直接在模板渲染的时候抛异常!! 

假设在我们的项目templates文件夹中有如下结构的模板文件:

├── article
│   ├── detail.html
│   └── index.html
├── footer.html
├── header.html
├── index.html
└── search├── detail.html└── index.html

r := gin.Default()

LoadHTMLGlob模板加载匹配模式

 r.LoadHTMLGlob("templates/*.html")    如果是这种模式就只能加载顶层的3个html文件,子目录中的文件无法加载

 r.LoadHTMLGlob("templates/**/*.html")   这种方式就只能加载子目录article, search中一共4个文件

r.LoadHTMLGlob("template/**/*")  这种模式 只能加载子目录中的所有文件或者文件夹,顶层的3个模板无法加载

r.LoadHTMLGlob("template/**")  这种模式 可以加载所有的文件和目录(坑,模板编译时直接报异常, 不能使用这种方式!)

上面的4种方式加载模板对于我们上面的模板结构都不可用,直接抛弃! 

上面的方式只能适用于没有子目录的模板加载

filepath.WalkDir  + LoadHTMLFiles() 的方式加载模板

对于我们上面的模板结构只能采用LoadHTMLFiles()方式加载了, 使用这个方式加载,我们需要先自己加载我们需要的模板文件, 这个就需要使用filepath.WalkDir 这个目录遍历大杀器出场了。废话补多少直接删代码:

// 模板文件加载var tplFiles []stringfilepath.WalkDir("templates", func(path string, d fs.DirEntry, err error) error {if !d.IsDir() && strings.HasSuffix(d.Name(), ".html") {// 非目录,且是.html结尾的文件加入到模板文件列表tplFiles = append(tplFiles, path)}return nil})r.LoadHTMLFiles(tplFiles...) // 加载html模板

 在gin控制器中通过.HTML方法使用模板

这个非常简单直接用HTML方法即可。 需要注意的是这里的模板名称是很讲究的,我们来看一下这个HTML方法的原型: func (c *gin.Context) HTML(code int, name string, obj any)   

这里第一个参数是http的状态码一般都是200即可, 第二个参数name 就是我们要渲染的模板的名称,这里的名称默认是你加载的文件的不区分目录的文件名, 由于默认不区分目录,所以如果你有多个同名的文件,则必须在对应的文件中使用 define对文件名进行定义,如: {{ define "index.html"}}   你的模板内容  {{end}}   。  如果你加载的文件名每个都是唯一的,则不需要定义也可以直接使用。


r.GET("/index", func(c *gin.Context) {// 注意这里的第二个参数 模板名是很有讲究的c.HTML(http.StatusOK, "index.html", gin.H{"title": "Main website",})
})
r.Run(":8080")

html模板文件示例和模板包含命名定义使用示例

index.html 示例:

注意,由于index.html文件名称有重复,所以这里我们必须使用define对文件名进行定义,否则index.html加载的就可能不是你期望的文件!!!

另外这里我们使用内置函数 template 对另外2个公共的模板文件进行加载。 {{template "xxx.html" .}}

{{define "index.html"}}
<!DOCTYPE html>
<html><head>{{template "header.html" .}}</head><body><div class="container-fluid"><H1>Hello Gin HTML</H1><!--- footer --->{{template "footer.html" .}}</div></body>
</html>
{{end}}

head.html

这个head.html文件名是唯一的,所以不需要是哟共define定义也可使用, 注意这里的标题 {{.title}} 这个直接使用了 c.HTML方法的第三个参数中传递的动态变量

<meta charset="utf-8" />
<metaname="viewport"content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<title>{{.title}}</title>

footer.html

<!--- footer --->
<footer style="height: 100px; background: #1b1c1d"><div style="text-align: center; font-size: 14px; padding-top: 50px">By<a href="http://dev.tekin.cn" target="_blank">{{.title}}</a></div>
</footer>

article/index.html文件内容

注意这里的define定义的文件名 {{ define "article/index.html"}}   我们一般以当前文件所在的模板文件夹下的相对路径来命名。 在c.HTML里面使用的时候我们就使用 c.HTML(200, "article/index.html", nil) 即可。

{{ define "article/index.html"}}
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Article index</title><link rel="stylesheet" href="">
</head>
<body><h1>Hello my article</h1>
</body>
</html>{{end}}

自定义模板渲染器

你可以使用自定义的 html 模板渲染

import "html/template"func main() {router := gin.Default()html := template.Must(template.ParseFiles("file1", "file2"))router.SetHTMLTemplate(html)router.Run(":8080")
}

自定义分隔符

r.Delims("{[{", "}]}") // 自定义模板分隔符 这个一般情况下我们保持默认即可

自定义模板功能

这个就是使用.SetFuncMap加载我们自定义的函数进去就可以。 推荐在c.HTML里面绑定对象的方式调用对象方法更方便,调用方式为 将函数名换为   对象名.方法名

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,})router.LoadHTMLFiles("templates/index.html")router.GET("/raw", func(c *gin.Context) {c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{"now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),})})router.Run(":8080")
}

在模板中使用我们自定义的函数:

Date: {[{.now | formatAsDate}]}   这个是使用管道符 | 方式,

也可以这样使用  Date: {[{formatAsDate  .now }]}  如果是多个参数用空格分开即可。

 附录 go内置的默认模板函数

func builtins() FuncMap {return FuncMap{"and":      and,"call":     call,"html":     HTMLEscaper,"index":    index,"slice":    slice,"js":       JSEscaper,"len":      length,"not":      not,"or":       or,"print":    fmt.Sprint,"printf":   fmt.Sprintf,"println":  fmt.Sprintln,"urlquery": URLQueryEscaper,// Comparisons"eq": eq, // =="ge": ge, // >="gt": gt, // >"le": le, // <="lt": lt, // <"ne": ne, // !=}
}

gin框架HTML渲染使用总结:

1. gin框架中渲染模板必须要先加载,如果模板文件中没有子目录可以使用 LoadHTMLGlob() ,如果有子目录推荐使用 filepath.WalkDir  + LoadHTMLFiles() 的方式加载模板;

2. 模板名称默认为加载的文件的忽略目录的文件名, 如果有多个同名文件,则默认使用功能的是第一个加载的模板文件;

3. 在模板中包含其他模板可以使用template函数进行加载包含,即 {{template "xxx.html" .}}

4. gin中模板渲染使用c.HTML方法,这个方法有3个参数,第一个是http状态码,第二个是模板名称,第三个是要传递给模板的变量数据, 这个我们一般使用map数据结构

5. 自定义模板函数实际上就是将自己定义的函数使用 r.SetFuncMap(template.FuncMap{ "模板中使用的函数名": 函数名,})

6. 一般情况下我们可以通过在c.HTML的第三个参数里面绑定一个对象来代替自定义函数, 直接在模板中调用对象的方法更加方便和简洁,不需要另外绑定函数即可使用。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词