Search code examples
gogo-templatesgo-gin

How to make templates work with gin framework?


I am newbie to golang. To learn it I have started with a simple web app using gin framework. I have followed the gin doc & configured template file but not able to make it work. I am getting an error -

panic: html/template: pattern matches no files: `templates/*`

goroutine 1 [running]:
html/template.Must
  /usr/local/Cellar/go/1.5.2/libexec/src/html/template/template.go:330
github.com/gin-gonic/gin.(*Engine).LoadHTMLGlob
  /Users/ameypatil/deployment/go/src/github.com/gin-gonic/gin/gin.go:126
main.main()
  /Users/ameypatil/deployment/go/src/github.com/ameykpatil/gospike/main.go:17

Below is my code -

package main

import (
    "net/http"

    "github.com/gin-gonic/gin"
)

func main() {
    //os.Setenv("GIN_MODE", "release")
    //gin.SetMode(gin.ReleaseMode)

    // Creates a gin router with default middleware:
    // logger and recovery (crash-free) middleware
    router := gin.Default()

    router.LoadHTMLGlob("templates/*")
    //router.LoadHTMLFiles("templates/index.tmpl")

    router.GET("/", func(c *gin.Context) {
        c.HTML(http.StatusOK, "index.tmpl", gin.H{
            "title": "GoSpike",
        })
    })

    // By default it serves on :8080 unless a
    // PORT environment variable was defined.
    router.Run(":4848")
}

My directory structure is

- gospike
--- templates
------index.tmpl
--- main.go

go install command does not give any error

but on actually running, it gives the above error. I searched & there were similar issues logged on gin's github repo but they are closed now. I have tried various things but I guess I am missing something obvious. What am I missing?


Solution

  • I'm guessing the issue is that you're using a relative filepath to access your templates.

    If I compile and run your code from the gospike directory, it works fine. But if I run gospike from any other directory, I get the same error you were seeing.

    So either you need to always run gospike in the parent directory of templates, or you need to use the absolute path. You could either hard code it:

    router.LoadHTMLGlob("/go/src/github.com/ameykpatil/gospike/templates/*")
    

    or you could do something like

    router.LoadHTMLGlob(filepath.Join(os.Getenv("GOPATH"),
        "src/github.com/ameykpatil/gospike/templates/*"))
    

    but that will fail if you have multiple paths set in your GOPATH. A better long-term solution might be setting a special environment variable like TMPL_DIR, and then just using that:

    router.LoadHTMLGlob(filepath.Join(os.Getenv("TMPL_DIR"), "*"))