文章目录
渲染HTML模板
注:本文基于github.com/gin-gonic/gin v1.7.7依赖进行讲解
1.LoadHTMLFiles方法渲染1个HTML模板
Gin框架中使用LoadHTMLGlob()或者LoadHTMLFiles()方法进行HTML模板渲染
LoadHTMLGlob()方法是加载一坨模板文件;
LoadHTMLFiles()方法是加载指定名字的模板文件;
模板通常都放在templates文件夹下的
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.LoadHTMLFiles("templates/index.tmpl") //模板解析
r.GET("/index", func(c *gin.Context) {
//HTML是*Context的一个方法,需要传入3个参数(code int, name string, obj interface{});无返回值
//code是http响应的状态码,比如写200;name 是模板的名称(当模板没有通过define命名的时候,默认模板名字就是文件名),
//可以把H理解成一个json格式的
//返回的是渲染好的模板文件 ; 模板渲染
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "liwnezhou",
})
})
r.Run()
}
<!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>
2.define定义模板名字LoadHTMLFiles渲染多个HTML模板
通过define给不同的模板定义不同的名字
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.LoadHTMLFiles("templates/posts/index.tmpl", "templates/users/index.tmpl") //模板解析
r.GET("/p", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
"title": "liwnezhou",
})
})
r.GET("/u", func(c *gin.Context) {
c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
"title": "lln",
})
})
r.Run()
}
{{define "posts/index.tmpl"}}
<!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}}
{{define "users/index.tmpl"}}
<!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}}
3.define定义模板名字LoadHTMLGlob渲染多个HTML模板
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/**/*") //这个**代表的是所有目录, *代表的是所有文件 ;假如templates文件夹下面没有posts文件夹与users文件夹,模板文件都是直接放在templates文件夹下,则写成templates/* 即可
r.GET("/p", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
"title": "liwnezhou",
})
})
r.GET("/u", func(c *gin.Context) {
c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
"title": "lln",
})
})
r.Run()
}
{{define "posts/index.tmpl"}}
<!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}}
{{define "users/index.tmpl"}}
<!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}}
4.LoadHTMLFiles方法不会脚本注入
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.LoadHTMLFiles("index.tmpl")//也可以写成 r.LoadHTMLFiles("./index.tmpl")
r.GET("/u", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
"bj": "<a href='https://liwenzhou.com'>李文周的博客</a>",
})
})
r.Run()
}
{{define "posts/index.tmpl"}}
<!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>
{{.bj}}
</body>
</html>
{{end}}
5.html\template\FuncMap类型及html\template\HTML类型及SetFuncMap方法及来脚本注入
即相信用户不会脚本注入
package main
import (
"github.com/gin-gonic/gin"
"html/template"
"net/http"
)
func main() {
r := gin.Default()
//gin框架中给模板添加自定义模板函数
//必须放在解析模板之前,SetFuncMapo是 *Engine的一个方法,传入一个参数(funcMap template.FuncMap),无返回值
r.SetFuncMap(template.FuncMap{
"safe": func(str string) template.HTML {
return template.HTML(str)
},
})
r.LoadHTMLFiles("index.tmpl")
r.GET("/u", func(c *gin.Context) {
c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
"bj": "<a href='https://liwenzhou.com'>李文周的博客</a>",
})
})
r.Run()
}
{{define "posts/index.tmpl"}}
<!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>
{{.bj | safe}}
</body>
</html>
{{end}}
6.自定义模板及Delims方法及pipeline概念
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,
})
router.LoadHTMLFiles("1.tmpl")
router.GET("/raw", func(c *gin.Context) {
c.HTML(http.StatusOK, "1.tmpl", map[string]interface{}{
"now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
})
})
router.Run(":8080")
}
<!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>
{[{.now}]}
Date: {[{.now | formatAsDate}]}
</body>
</html>