Gin渲染
HTML渲染
我们首先定义一个存放模板文件的templates文件夹,然后在内部按照业务分别定义一个posts文件夹和一个users文件夹。
posts/index.html文件的内容如下:
{{define "posts/index.html"}} // 如果两个文件夹都有同名的index.html文件,需要define定义一个模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>posts/index</title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}users/index.html文件的内容如下:
{{define "users/index.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}Gin框架中使用LoadHTMLGlob() (加载一堆模板文件)或者LoadHTMLFiles() (加载指定名字的模板文件)方法进行HTML模板渲染。
package main
import(
"github.com/gin-gonic/gin"
)
func main(){
r := gin.Default()
r.LoadHTMLGlob("templates/**/*")
r.GET("/posts/index",func(c *gin.Context){
c.HTML(http.StatusOK,"posts/index.html",gin.H{// 模板渲染
"title":"posts/index"
})
})
r.GET("users/index",func(c *gin.Context){
c.HTML(http.StatusOK,"users/index.html",gin.H{
"title":"users/index"
})
})
r.Run(":8080")
}自定义模板函数
定义一个不转义相应内容的safe模板函数如下:
func main(){
router := gin.Default()
router.SetFuncMap(template.FuncMap{
"safe":func(str string)template.HTML{
return template.HTML(str)
},
})
router.LoadHTMLFiles("./index.tmpl")
router.GET("/index",func(c *gin.Contex){
C.HTML(http.StatucOK,"index.tmpl","<a href='https://liwenzhou.com'>李文周的博客</a>")
})
router.Run(":8080")
}在index.tmpl中使用定义好的safe模板函数:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>修改模板引擎的标识符</title>
</head>
<body>
<div>{{. | safe}}</div>
</body>
</html>静态文件处理
当我们渲染的HTML文件中引用了静态文件时,我们只需要按照以下方式,在渲染页面前调佣gin.Static方法即可。
func main (){
r := gin.Default()
r.Static("/static","./static")
r.LoadHTMLGlob("templates/**/*")
r.Run(":8080")
}使用模板继承(使用少)
Gin框架默认都是使用单模板,如果需要使用block template功能,
可以通过"github.com/gin-contrib/multitemplate"库实现,具体示例如下:
首先,假设我们项目目录下的templates文件夹下有以下模板文件,其中home.tmpl和index.tmpl继承了base.tmpl:
templates
|--includes
| |--home.tmpl
| |--index.tmpl
|--layouts
| |--base.tmpl
|--scripts.tmpl
然后我们定义一个loadTemplates函数如下:
func loadTemplates(templatesDir string)multitemplate.Renderer{
r := multitemplate.NewRenderer()
layouts, err := filepath.Glob(templatesDir + "/layouts/*.tmpl")
if err != nil {
panic(err.Error())
}
includes, err := filepath.Glob(templateDir + "/includes/*.tmpl")
if err != nil {
panic(err.Error())
}
for _, include := range includes{
layoutCopy := make([]string, len(layouts))
copy(layoutCopy,layouts)
files := append(layoutCopy,include)
r.AddFromFiles(filepath.Base(include),files...)
}
return r
}我们在main函数中:
func indecFunc(c *gin.Context){
c.HTML(http.StatusOK,"index.tmpl",nil)
}
func homeFunc(c *gin.Context){
c.HTML(http.StatusOK,"home.tmpl",nil)
}
func main(){
r := gin.Defaule()
r.HTMLRender = loadTemplates("./templates")
r.GET("/index",indexFunc)
r,GET("/home",homeFunc)
r.Run()
}补充文件路径处理
关于模板文件和静态文件的路径,我们需要根据公司/项目的要求进行设置。
可以使用下面的函数获取当前执行程序的路径。
func getCurrentPath() string {
if ex,err := os.Executable(); err == nil {
return filepath.Dir(ex)
}
return "./"
}