你如何在 subfolders/packages 中使用 Go 1.16 嵌入功能?
How do you use Go 1.16 embed features in subfolders/packages?
Go 1.16 已发布,我想使用新的嵌入功能。如果一切都在主包中,我可以让它工作。但不清楚如何处理从 subfolders/packages 访问资源。尝试在 embed.FS 支持下完成。
例如我有一个 main.go 和一个处理程序中的 HTTP 处理程序 package/folder
如果我将处理程序放在 main 中,它就可以工作。如果我把它放在处理程序包中,它就找不到模板。我得到:
handlers/indexHandler.go:11:12: pattern templates: no matching files found exit status 1
同样,如果我从 / 提供图像,我可以让它提供静态文件夹中的图像。但是我不能同时为来自 / 的处理程序和来自 / 的 static/images 提供服务。如果我将图像放在 /static/ 上,它找不到图像。
我认为这与相对路径有关。但是我无法通过反复试验找到合适的组合...依赖这些功能会不会太早了?
之前我用的是go-rice,没有这些问题。但我想尽可能多地使用std库。
main.go:
package main
import (...)
//go:embed static
var static embed.FS
func main() {
fsRoot, _ := fs.Sub(static, "static")
fsStatic := http.FileServer(http.FS(fsRoot))
http.Handle("/", fsStatic)
http.HandleFunc("/index", Index)
http.ListenAndServe(":8080", nil)
}
handlers/indexHandler.go:
package handlers
import (...)
//go:embed templates
var templates embed.FS
// Index handler
func Index(w http.ResponseWriter, r *http.Request) {
tmpl := template.New("")
var err error
if tmpl, err = tmpl.ParseFS(templates, "simple.gohtml"); err != nil {
fmt.Println(err)
}
if err = tmpl.ExecuteTemplate(w, "simple", nil); err != nil {
log.Print(err)
}
}
结构如下...
.
├── go.mod
├── go.sum
├── handlers
│ └── indexHandler.go
├── main.go
├── static
│ ├── css
│ │ └── layout.css
│ └── images
│ └── logo.png
└── templates
└── simple.gohtml
我终于想通了...
您可以将模板文件夹保留在主文件夹中,然后从那里嵌入它们。然后你需要将 FS 变量注入到另一个处理程序包中。想通了总是容易的。
例如
package main
//go:embed templates/*
var templateFs embed.FS
func main() {
handlers.TemplateFs = templateFs
...
package handlers
var TemplateFs embed.FS
func handlerIndex() {
...
tmpl, err = tmpl.ParseFS(TemplateFs, "templates/layout.gohtml",...
...
目前在 Go 1.17 中,嵌入不支持 subfolders/packages,参见 https://github.com/golang/go/issues/41191#issuecomment-686616556
Go 1.16 已发布,我想使用新的嵌入功能。如果一切都在主包中,我可以让它工作。但不清楚如何处理从 subfolders/packages 访问资源。尝试在 embed.FS 支持下完成。
例如我有一个 main.go 和一个处理程序中的 HTTP 处理程序 package/folder
如果我将处理程序放在 main 中,它就可以工作。如果我把它放在处理程序包中,它就找不到模板。我得到:
handlers/indexHandler.go:11:12: pattern templates: no matching files found exit status 1
同样,如果我从 / 提供图像,我可以让它提供静态文件夹中的图像。但是我不能同时为来自 / 的处理程序和来自 / 的 static/images 提供服务。如果我将图像放在 /static/ 上,它找不到图像。
我认为这与相对路径有关。但是我无法通过反复试验找到合适的组合...依赖这些功能会不会太早了?
之前我用的是go-rice,没有这些问题。但我想尽可能多地使用std库。
main.go:
package main
import (...)
//go:embed static
var static embed.FS
func main() {
fsRoot, _ := fs.Sub(static, "static")
fsStatic := http.FileServer(http.FS(fsRoot))
http.Handle("/", fsStatic)
http.HandleFunc("/index", Index)
http.ListenAndServe(":8080", nil)
}
handlers/indexHandler.go:
package handlers
import (...)
//go:embed templates
var templates embed.FS
// Index handler
func Index(w http.ResponseWriter, r *http.Request) {
tmpl := template.New("")
var err error
if tmpl, err = tmpl.ParseFS(templates, "simple.gohtml"); err != nil {
fmt.Println(err)
}
if err = tmpl.ExecuteTemplate(w, "simple", nil); err != nil {
log.Print(err)
}
}
结构如下...
.
├── go.mod
├── go.sum
├── handlers
│ └── indexHandler.go
├── main.go
├── static
│ ├── css
│ │ └── layout.css
│ └── images
│ └── logo.png
└── templates
└── simple.gohtml
我终于想通了...
您可以将模板文件夹保留在主文件夹中,然后从那里嵌入它们。然后你需要将 FS 变量注入到另一个处理程序包中。想通了总是容易的。
例如
package main
//go:embed templates/*
var templateFs embed.FS
func main() {
handlers.TemplateFs = templateFs
...
package handlers
var TemplateFs embed.FS
func handlerIndex() {
...
tmpl, err = tmpl.ParseFS(TemplateFs, "templates/layout.gohtml",...
...
目前在 Go 1.17 中,嵌入不支持 subfolders/packages,参见 https://github.com/golang/go/issues/41191#issuecomment-686616556