# Gin渲染 参考博客:[Gin框架介绍及使用](https://www.liwenzhou.com/posts/Go/gin/) ## HTML渲染 我们首先定义一个存放模板文件的`templates`文件夹,然后在其内部按照业务分别定义一个`posts`文件夹和一个`users`文件夹。 `posts/index.html`文件的内容如下: ```html {{define "posts/index.html"}} posts/index {{.title}} {{end}} ``` `users/index.html`文件的内容如下: ```html {{define "users/index.html"}} users/index {{.title}} {{end}} ``` Gin框架中使用`LoadHTMLGlob()`或者`LoadHTMLFiles()`方法进行HTML模板渲染。 ```go 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`模板函数如下: ```go 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", "李文周的博客") }) router.Run(":8080") } ``` 在`index.tmpl`中使用定义好的`safe`模板函数: ```html 修改模板引擎的标识符
{{ . | safe }}
``` ## 静态文件处理 当我们渲染的HTML文件中引用了静态文件时,我们只需要按照以下方式在渲染页面前调用`gin.Static`方法即可。 ```go 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`: ```bash templates ├── includes │ ├── home.tmpl │ └── index.tmpl ├── layouts │ └── base.tmpl └── scripts.tmpl ``` 然后我们定义一个`loadTemplates`函数如下: ```go 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`函数中 ```go 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() } ``` ## 补充文件路径处理 关于模板文件和静态文件的路径,我们需要根据公司/项目的要求进行设置。可以使用下面的函数获取当前执行程序的路径。 ```go func getCurrentPath() string { if ex, err := os.Executable(); err == nil { return filepath.Dir(ex) } return "./" } ``` ## 返回Json ```go 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") } ``` --- > 作者: [Hollis](https://www.xuexiqu.cn/) > URL: https://www.xuexiqu.cn/golang/gin/gin_rendering/