HTML 模板渲染
- 解释: Gin⽀持加载HTML模板, 然后根据模板参数进⾏配置并返回相应的数据
- 在项目中新建一个用来存放模板的目录,添加一个模板 templates/index.tmpl
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ .headName }}</title>
</head>
<body>
<h1>{{ .tableName }}</h1>
</body>
</html>
- 后端代码
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
//1.通过Router调用LoadHTMLGlob()加载模板,此处表示加载templates下的所有模板
router.LoadHTMLGlob("templates/*")
//使用LoadHTMLFiles()也可以加载指定模板
//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
//2.注册获取模板路由
router.GET("/index", HtmlFunc)
router.Run(":8080")
}
//获取页面接口
func HtmlFunc(c *gin.Context) {
//3.通过Context调用HTML()响应指定模板,并将数据渲染到模板中
c.HTML(http.StatusOK, "index.tmpl", gin.H{"headName":"网站标题","tableName": "内部标题"})
}
- 也就是将后端数据填充到模板中并响应
自定义模板引擎与模板函数
- 自定义模板引擎
package main
//1.导入"html/template"
import (
"github.com/gin-gonic/gin"
"net/http"
"html/template"
)
func main() {
router := gin.Default()
//2.通过template调用Must()
html := template.Must(template.ParseFiles("file1", "file2"))
router.SetHTMLTemplate(html)
router.Run(":8080")
}
- 自定义模板函数
//1.导入"html/template"
import (
"github.com/gin-gonic/gin"
"html/template"
"net/http"
)
func main() {
router := gin.Default()
//2.创建自定义模板函数通过template调用FuncMap{}存入map中
//其中key为页面上执行该函数的名
tempMap := template.FuncMap{
"safe": func(str string) template.HTML {
return template.HTML(str)
},
}
//3.解析模板(注意点要在调用FunMap以后)
router.SetFuncMap(tempMap)
//4.加载模板
router.LoadHTMLFiles("./index.tmpl")
//5.注册返回模板的路由
router.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", "<a href='https://baidu.com'>百度</a>")
})
router.Run(":8080")
}
- 使用自定义模板函数的模板示例,当请求该接口时就胡出现一个转译与不转译的效果
<!DOCTYPE html> <html lang="zh-CN"> <head>
<title>自定义模板函数</title>
</head> <body> <div>{{ . | safe }}</div>
</body>
</html>
模板继承
- 解释: 假设现在有三个模板,index.tmpl与home.tmpl这两个模板继承使用了base.tmpl中的东西
- Gin中默认都使用单模板,需要使⽤ block template 功能要手动下载安装一个包
"github.com/gincontrib/multitemplate"
- 然后需要定义一个 loadTemplates 函数,如下
package main
//1.导入"github.com/gin-contrib/multitemplate"
import (
"github.com/gin-contrib/multitemplate"
"github.com/gin-gonic/gin"
"net/http"
"path/filepath"
)
//2.添加一个名为 loadTemplates 函数,该函数读取公共的base模板
//与需要继承该模板的index.tmpl与home.tmpl,将公共模板的数据添加到
//index.tmpl与home.tmpl中后,格式化并返回 multitemplate.Renderer
func loadTemplates() multitemplate.Renderer {
//1.通过multitemplate 调用NewRenderer()获取到Renderer
r := multitemplate.NewRenderer()
//2.读取公共的base模板
layouts, err := filepath.Glob("/layouts/base.tmpl")
if err != nil {
panic(err.Error())
}
//3.读取需要继承公共模板的index.tmpl与home.html,这两个模板都在includes目录下
includes, err := filepath.Glob("/includes/*.tmpl")
if err != nil {
panic(err.Error())
}
//4.为layouts/和includes/⽬录⽣成 templates map
for _, include := range includes {
//4.1获取base模板长度创建一个map
layoutCopy := make([]string, len(layouts))
//4.2将base模板中的内容复制到map中
copy(layoutCopy, layouts)
//4.3将存有base内容的map追加到需要继承这些内容的模板上
files := append(layoutCopy, include)
//4.4格式化这些拿到需要继承数据的模板
r.AddFromFiles(filepath.Base(include), files...)
}
//5.返回
return r
}
func main() {
r := gin.Default()
//3.通过自己创建loadTemplates()函数加载模板
r.HTMLRender = loadTemplates()
//4.注册返回模板的路由
r.GET("/index", indexFunc)
r.GET("/home", homeFunc)
r.Run()
}
func indexFunc(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", nil)
}
func homeFunc(c *gin.Context) {
c.HTML(http.StatusOK, "home.tmpl", nil)
}
- 后端代码写好后,模板中需要定义html嵌套模板的代码才可以实现该功能
静态文件响应
- 在一个服务中请求后端,可能会将项目中的静态数据响应回去,例如图片在页面中的展示
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
router := gin.Default()
// 下⾯测试静态⽂件服务
// 显示当前⽂件夹下的所有⽂件/或者指定⽂件
router.StaticFS("/showDir", http.Dir("."))
//显示/bin目录下的文件
router.StaticFS("/files", http.Dir("/bin"))
//Static提供给定⽂件系统根⽬录中的⽂件。
//注意点此处传递了两个参数"/files"是页面中引用静态文件使用的地址
//后面的/bin是静态文件在本地的地址,也就是后端/bin与前端的/files
//做一个映射,前端通过/finles找到文件
//router.Static("/files", "/bin")
router.StaticFile("/image", "./assets/image.jpg")
router.Run(":8080")
}
2.如果要展示一个图片,页面中要有标签