如何解决模板错误:模式没有匹配到任何文件

huangapple go评论89阅读模式
英文:

How to solve template: pattern matches no files

问题

当我从主要的go文件之外的另一个go文件访问文件时,如何处理文件路径。

在other.go文件中,我尝试运行ParseFS,但是它给出了"template: pattern matches no files: templates/test.tmpl"错误。这是我的文件树结构。

├── go.mod
├── main
│   └── main.go
└── other
    ├── other.go
    └── templates
        └── test.tmpl

other/other.go

package other

import (
    "embed"
    "fmt"
    "html/template"
)

var templateFS embed.FS

func Check() error {
    _, err := template.New("email").ParseFS(templateFS, "templates/"+"test.tmpl")

    if err != nil {
        fmt.Println(err)
    }
    return nil
}

main/main.go

func main() {
    err := other.Check()

    if err != nil {
        fmt.Println(err)
    }
}
英文:

How to handle file path when i am accessing file from other go file than main.

in other.go file i am trying to run ParseFS but it's giving the template: pattern matches no files: templates/test.tmpl error. Here is my file tree.

├── go.mod
├── main
│   └── main.go
└── other
    ├── other.go
    └── templates
        └── test.tmpl

other/other.go

package other

import (
	"embed"
	"fmt"
	"html/template"
)

var templateFS embed.FS

func Check() error {
	_, err := template.New("email").ParseFS(templateFS, "templates/"+ "test.tmpl")

	if err != nil {
		fmt.Println(err)
	}
	return nil
}

main/main.go

func main() {
	err :=othher.Check()

	if err != nil {
		fmt.Println(err)
	}
}

答案1

得分: 7

Go是一种静态链接语言。无论你写的源代码是什么,最终go工具都会将其编译成可执行的二进制文件。运行二进制文件时不需要源代码文件。

embed包提供了一种在可执行的二进制文件中包含静态文件的方法,你可以在运行时访问这些文件(当你运行应用程序时,原始的包含文件不需要存在)。

然而,go工具不会自动找出你想要包含在二进制文件中的文件和文件夹。它显然不会包含源代码或模块文件夹中的所有内容。

告诉工具你想要包含哪些文件的方法是在你想要存储文件的变量之前加上特殊的//go:embed注释。

所以在你的情况下,你需要在templateFS变量之前加上以下注释:

//go:embed templates/*
var templateFS embed.FS

还要注意,只有在导入embed包的情况下嵌入才起作用。在你的情况下,这是“自然”发生的,因为你使用了embed.FS类型(该类型需要导入embed包)。但是,如果你将文件包含在string[]byte类型的变量中,那就不需要导入embed,在这种情况下,你需要进行一个“空白”导入,如下所示:

import _ "embed"

更多详细信息请参阅embed包的文档。

相关问题请参考:https://stackoverflow.com/questions/13904441/whats-the-best-way-to-bundle-static-resources-in-a-go-program/28071360#28071360

英文:

Go is a statically linked language. Whatever source you write, in the end the go tool will compile it into an executable binary. The source files will not be required afterwards to run the binary.

The embed package gives you a mean to include static files in the executable binary which you can access at runtime (the original, included files don't need to be present when you run the app).

However, the go tool will not magically find out what files and folders you want to include in your binary. It will obviously not include everything you have in your source or module's folder.

The way to tell which files you want to be included is a special //go:embed comment preceding the variable you want the files to be stored in.

So in your case you have to put the following comment before your templateFS variable:

//go:embed templates/*
var templateFS embed.FS

Also note that embedding only works if you import the embed package. This "naturally" happens in your case because you used the embed.FS type (which requires importing the embed package), but if you would include a file in a variable of string or []byte type, that wouldn't require importing embed, in which case you'd have to do a "blank" import like

import _ "embed"

More details are in the package doc of embed.

See related question: https://stackoverflow.com/questions/13904441/whats-the-best-way-to-bundle-static-resources-in-a-go-program/28071360#28071360

huangapple
  • 本文由 发表于 2022年3月8日 20:12:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/71394849.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定