Gin: How can I use html template?

Created on 3 Jul 2014  路  8Comments  路  Source: gin-gonic/gin

Hello.
Thank you for sharing nice framework.

I wonder how can I use html template in gin framework.

I've tried below,

html := template.ParseFiles("file1", "file2")
r.HTMLTemplates = html

Then I've got an error bellow.

multiple-value "html/template".ParseFiles() in single-value context

And I've researched bit more.
Finally discovered Context.HTML.

func render(c *gin.Context) {
    c.HTML(200, "template/index.html", gin.H{})
}

but it gave me a blank page.

How can I use html template?

question

Most helpful comment

I just write a finder to find templates,

func TemplatesFinder(engine *gin.Engine, pathOfRoot, templateDirName string) {
    dir := gin.Dir(pathOfRoot, true)
    file, err := dir.Open(templateDirName)
    util.PanicError(err)
    defer file.Close()
    dirs, err := file.Readdir(10)
    util.PanicError(err)

    templatePages := make([]string, 0, 10)
    dirStack := collections.NewStack(10)
    for _, v := range dirs {
        if v.IsDir() {
            fileNode := v.Name()
            dirStack.Push(fileNode)
        } else {
            templatePages = append(templatePages, templateDirName + "/" + v.Name())
        }
    }

    // range every dir, and find sub dirs
    for {
        if rootDir, ok := dirStack.Pop(); ok {
            tmpDir := fmt.Sprint(rootDir)

            dir := gin.Dir(templateDirName + "/" + tmpDir, true)
            file, err := dir.Open(".")
            util.PanicError(err)
            defer file.Close()
            dirs, err = file.Readdir(10)
            for _, v := range dirs {
                path := tmpDir + "/" + v.Name()
                if v.IsDir() {
                    dirStack.Push(tmpDir)
                } else {
                    templatePages = append(templatePages, templateDirName + "/" + path)
                }
            }
        } else {
            log.Logger.Debug("has no elements....")
            break
        }
    }

    temp, err := template.ParseGlob("templates/*\\.tmpl")
    util.PanicError(err)

    for _, v := range temp.Templates() {
        log.Logger.Debug("templates: %v", v.Name())
    }

    log.Logger.Debug("all template pages: %v", templatePages)
    engine.LoadHTMLFiles(templatePages...)
}

and u can use like this just assume your templates are in templates directory, and main file is in the root of project:

g = gin.New()
TemplatesFinder(g, ".", "templates")

All 8 comments

Hi,

Look at the example in the README[0], that should work.

The error, "multiple valie {..} in single-value context", is because template.ParseFiles returns multiple values, a pointer to a template and an error. The right usage would be:

tmpl, err := template.ParseFiles("file1", "file2")

Edit: I saw that the second example in the README is wrong. Fixing.

[0] https://github.com/gin-gonic/gin/blob/master/README.md#html-rendering

Hi @alexandernyquist

Thanks for the quick response.

I modifed the code and it runs without errors.
But I can't see the template on web.
What should I do more?

Regards,

I've created a simple gist[0] which works for me. Can you please try it out?

[0] https://gist.github.com/alexandernyquist/e7e9a00ff2ab40a9252a

Thanks for the example.

But it gave me same result. (blank page)

I've got templates from https://github.com/jadekler/git-go-websiteskeleton

type Data struct {
Name string
}

func main() {
html,err := template.ParseFiles("templates/home/home.html", "templates/layout.html")
r.HTMLTemplates = html
if err != nil {
var stack [4096]byte
runtime.Stack(stack[:], false)
log.Printf("%q\n%s\n", err, stack[:])

}

//r.LoadHTMLTemplates("frontend/static/templates/*")

r.GET("/test", func(c *gin.Context){
    //c.String(200, "pang pong porobong")
    c.HTML(200, "home.html", Data{"@dorijastyle"})
    //frontend.GetHomePage(c)
})

}

I added a new (simplified from git-go-websiteskeleton) example[0]. The key is to not include all templates outside the routes since that will cause redeclaration issues.

We should probably hare a more convenient way of doing this. Maybe a engine.LoadHTMLTemplateFiles(files...string) and engine.LoadHTMLTemplateGlob(pattern string)? That way, the user does not need to import html/template. Of course, shorter names would be nice ;)

[0] https://gist.github.com/alexandernyquist/1ee331db9f5bf0d577d6

Hi Alexander,
Thanks for the kind response.

I've tried it again, and it failed.
And I've got a panic but Golang didn't catched it. :(
Whole source correct logically.
I was confused because I'm a newbie of Golang.

So I 've tried a job in software bible.
"When software not work, delete it and install it again."

It works perfectly. :D

Thanks a lot!

I liked the idea of including two easy ways to load the templates, using glob and a list of files.

I just write a finder to find templates,

func TemplatesFinder(engine *gin.Engine, pathOfRoot, templateDirName string) {
    dir := gin.Dir(pathOfRoot, true)
    file, err := dir.Open(templateDirName)
    util.PanicError(err)
    defer file.Close()
    dirs, err := file.Readdir(10)
    util.PanicError(err)

    templatePages := make([]string, 0, 10)
    dirStack := collections.NewStack(10)
    for _, v := range dirs {
        if v.IsDir() {
            fileNode := v.Name()
            dirStack.Push(fileNode)
        } else {
            templatePages = append(templatePages, templateDirName + "/" + v.Name())
        }
    }

    // range every dir, and find sub dirs
    for {
        if rootDir, ok := dirStack.Pop(); ok {
            tmpDir := fmt.Sprint(rootDir)

            dir := gin.Dir(templateDirName + "/" + tmpDir, true)
            file, err := dir.Open(".")
            util.PanicError(err)
            defer file.Close()
            dirs, err = file.Readdir(10)
            for _, v := range dirs {
                path := tmpDir + "/" + v.Name()
                if v.IsDir() {
                    dirStack.Push(tmpDir)
                } else {
                    templatePages = append(templatePages, templateDirName + "/" + path)
                }
            }
        } else {
            log.Logger.Debug("has no elements....")
            break
        }
    }

    temp, err := template.ParseGlob("templates/*\\.tmpl")
    util.PanicError(err)

    for _, v := range temp.Templates() {
        log.Logger.Debug("templates: %v", v.Name())
    }

    log.Logger.Debug("all template pages: %v", templatePages)
    engine.LoadHTMLFiles(templatePages...)
}

and u can use like this just assume your templates are in templates directory, and main file is in the root of project:

g = gin.New()
TemplatesFinder(g, ".", "templates")
Was this page helpful?
0 / 5 - 0 ratings

Related issues

iiinsomnia picture iiinsomnia  路  3Comments

gplume picture gplume  路  3Comments

mastrolinux picture mastrolinux  路  3Comments

olegsobchuk picture olegsobchuk  路  3Comments

ccaza picture ccaza  路  3Comments