参考博客:Gin框架介绍及使用
HTML渲染
我们首先定义一个存放模板文件的templates
文件夹,然后在其内部按照业务分别定义一个posts
文件夹和一个users
文件夹。 posts/index.html
文件的内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
{{define "posts/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>posts/index</title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}
|
users/index.html
文件的内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
{{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>users/index</title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}
|
Gin框架中使用LoadHTMLGlob()
或者LoadHTMLFiles()
方法进行HTML模板渲染。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/**/*")
//r.LoadHTMLFiles("templates/posts/index.html", "templates/users/index.html")
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
模板函数如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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.Context) {
c.HTML(http.StatusOK, "index.tmpl", "<a href='https://liwenzhou.com'>李文周的博客</a>")
})
router.Run(":8080")
}
|
在index.tmpl
中使用定义好的safe
模板函数:
1
2
3
4
5
6
7
8
9
|
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>修改模板引擎的标识符</title>
</head>
<body>
<div>{{ . | safe }}</div>
</body>
</html>
|
静态文件处理
当我们渲染的HTML文件中引用了静态文件时,我们只需要按照以下方式在渲染页面前调用gin.Static
方法即可。
1
2
3
4
5
6
7
|
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
:
1
2
3
4
5
6
7
|
templates
├── includes
│ ├── home.tmpl
│ └── index.tmpl
├── layouts
│ └── base.tmpl
└── scripts.tmpl
|
然后我们定义一个loadTemplates
函数如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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(templatesDir + "/includes/*.tmpl")
if err != nil {
panic(err.Error())
}
// 为layouts/和includes/目录生成 templates map
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
函数中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
func indexFunc(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.Default()
r.HTMLRender = loadTemplates("./templates")
r.GET("/index", indexFunc)
r.GET("/home", homeFunc)
r.Run()
}
|
补充文件路径处理
关于模板文件和静态文件的路径,我们需要根据公司/项目的要求进行设置。可以使用下面的函数获取当前执行程序的路径。
1
2
3
4
5
6
|
func getCurrentPath() string {
if ex, err := os.Executable(); err == nil {
return filepath.Dir(ex)
}
return "./"
}
|
返回Json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
func main() {
r := gin.Default()
// 方法1:使用map
r.GET("/json01", func(c *gin.Context) {
data := gin.H{ // gin.H is a shortcut for map[string]any
"name": "tom",
"age": 26,
"gender": "male",
}
c.JSON(http.StatusOK, data)
})
// 方法2:使用struct,使用tag来定制json字段的名称。
r.GET("/json02", func(c *gin.Context) {
var person struct {
Name string `json:"name"` // 这里一定要是可导出的,否则json获取不到数据。如果想要指定json字段的名称,可以使用Tag。
Age int `json:"age"`
Gender string `json:"gender"`
}
person.Name = "Jane"
person.Age = 24
person.Gender = "female"
c.JSON(http.StatusOK, person) // 传入结构体类型的数据
})
r.Run(":9003")
}
|