3

我是golang的新手。为了学习它,我从一个使用gin框架的简单 Web 应用程序开始。我遵循了 gin doc 和配置的模板文件,但无法使其工作。我收到一个错误 -

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

下面是我的代码 -

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")
}

我的目录结构是

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

go install命令没有给出任何错误

但在实际运行时,它给出了上述错误。我搜索并在 gin 的 github repo 上记录了类似的问题,但它们现在已关闭。我尝试了各种各样的东西,但我想我错过了一些明显的东西。我错过了什么?

4

4 回答 4

7

我猜问题是您正在使用相对文件路径来访问您的模板。

如果我从gospike目录编译并运行您的代码,它工作正常。但是,如果我gospike从任何其他目录运行,我会得到与您看到的相同的错误。

所以要么需要一直运行gospike在 的父目录下templates,要么需要使用绝对路径。您可以对其进行硬编码:

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

或者你可以做类似的事情

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

但如果您在GOPATH. 一个更好的长期解决方案可能是设置一个特殊的环境变量,例如TMPL_DIR,然后使用它:

router.LoadHTMLGlob(filepath.Join(os.Getenv("TMPL_DIR"), "*"))
于 2016-06-26T19:39:39.450 回答
1

使用相对路径 glob 将起作用,您可以尝试编码

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

注意.表示当前目录的点号,gin.Engine 将templates根据当前目录的子目录加载模板。

于 2021-01-03T02:29:23.777 回答
1

这是我的做法。这将遍历目录并收集标有我的模板后缀(即 .html)的文件,然后我只包含所有这些文件。我在任何地方都没有看到这个答案,所以我想我把它贴出来。

// START UP THE ROUTER
router := gin.Default()

var files []string
filepath.Walk("./views", func(path string, info os.FileInfo, err error) error {
    if strings.HasSuffix(path, ".html") {
        files = append(files, path)
    }
    return nil
})

router.LoadHTMLFiles(files...)

// SERVE STATICS
router.Use(static.Serve("/css", static.LocalFile("./css", true)))
router.Use(static.Serve("/js", static.LocalFile("./js", true)))
router.Use(static.Serve("/images", static.LocalFile("./images", true)))

routers.LoadBaseRoutes(router)
routers.LoadBlog(router)

router.Run(":8080")
于 2021-01-10T20:39:02.347 回答
0

有一个多模板HTML 渲染来支持多模板。

您可以使用AddFromFiles添加多个文件:

r.AddFromFiles("index", "templates/base.html", "templates/index.html")
r.AddFromFiles("article", "templates/base.html", "templates/index.html", "templates/article.html")

或者在一个目录下加载多个文件:

package main

import (
    "path/filepath"

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

func main() {
    r := gin.New()

    r.HTMLRender = loadTemplates()

    // ...
}

func loadTemplates() multitemplate.Render {
    files, err := filepath.Glob("template/*.tmpl")
    if err != nil {
        panic("failed to load html templates: " + err.Error())
    }

    r := multitemplate.New()

    // Generate our templates map from our template/ directories
    for _, file := range files {
        r.AddFromFiles(filepath.Base(file), file)
    }

    // add other html templates directly
    r.Add("test.tmpl", someTemplate)

    return r
}

你可以在这个 repo 中看到更多你想要的 API,希望这篇文章有所帮助:)

于 2021-09-07T03:54:28.273 回答