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 "./" }