Gin: Supports template files with same name in different folders

Created on 2 Jun 2015  路  4Comments  路  Source: gin-gonic/gin

I have 2 template files with the same name. But they are in different folders, e.g. views/post/index.tmpl and views/user/index.tmpl. (It's common in Rails.) But currently the folder name is not allowed in context.HTML().

func main() {
    router := gin.Default()
    router.LoadHTMLGlob("views/post/index.tmpl")
    router.LoadHTMLGlob("views/user/index.tmpl")
    router.GET("/", func(context *gin.Context) {
        context.HTML(http.StatusOK, "post/index.tmpl", gin.H{ "title": "Main website" })
        //                           ^[ERROR] html/template: "post/index.tmpl" is undefined.
        //                           "views/post/index.tmpl" does not work either.
    })
    router.Run(":8080") // listen and serve on 0.0.0.0:8080
}

context.HTML(http.StatusOK, "index.tmpl", gin.H{ "title": "Main website" }) works, but it actually uses views/user/index.tmpl, because router.LoadHTMLGlob("views/user/index.tmpl") is called after router.LoadHTMLGlob("views/post/index.tmpl").

If gin does not support template files with same name in different folders, we have to make sure each template file name is unique, like post_index.tmpl, user_index.tmpl. It's not convenient.

Update:
Similar issue: #241 (Closed)

question

Most helpful comment

@vinceyuan yes, you can: place your template wherever you want:

Load them with a Glob:

router.LoadHTMLGlob("templates/**/*")

and use the {{define NAME}} directive

{{define post/index.tmpl}}
// your template
{{end}}

https://elithrar.github.io/article/approximating-html-template-inheritance/

you can architect your app whatever you want. Go and Gin are configuration over convention, that means you can do it whatever you want. Ruby on Rails is (convention of configuration).

Gin and Go philosophy itself does not force you to follow a pattern.

https://github.com/gin-gonic/gin/issues/320

All 4 comments

@vinceyuan You should read how *template.Template works. "post/index.tmpl" will not work either way using Gin or html/template directly.

http://golang.org/pkg/html/template/

router.LoadHTMLFile("views/post/index.tmpl", "views/post/index.tmpl")

or initialize your template manually then give it to gin:

tmpl := template.Must(template.ParseFile(...))
router.SetHTMLTemplate(tmpl)

Gin does not implement any template rendering, it uses the html template rendering provided by the standard library. Although , you can use your own renders .. but that is not the topic of this issue .

@manucorporat Thanks for the reply. You are right. I have known it is not gin's fault at #241 . But many developers who used Rails or Node.js(Express.js) have the habit of organizing templates this way. It's frustrating to see it is not supported when they try gin.

@vinceyuan yes, you can: place your template wherever you want:

Load them with a Glob:

router.LoadHTMLGlob("templates/**/*")

and use the {{define NAME}} directive

{{define post/index.tmpl}}
// your template
{{end}}

https://elithrar.github.io/article/approximating-html-template-inheritance/

you can architect your app whatever you want. Go and Gin are configuration over convention, that means you can do it whatever you want. Ruby on Rails is (convention of configuration).

Gin and Go philosophy itself does not force you to follow a pattern.

https://github.com/gin-gonic/gin/issues/320

@manucorporat Great trick. Thanks! {{ define "post/index.tmpl" }} works!

Was this page helpful?
0 / 5 - 0 ratings