12

Go 1.16 已经发布,我想使用新的嵌入功能。如果一切都在主包中,我可以让它工作。但目前尚不清楚如何处理从子文件夹/包访问资源。尝试使用 embed.FS 支持来做到这一点。

例如,我在处理程序包/文件夹中有一个 main.go 和一个 HTTP 处理程序

如果我将处理程序放在主要位置,它就可以工作。如果我把它放在处理程序包中,它就找不到模板。我得到:

handlers/indexHandler.go:11:12: pattern templates: no matching files found exit status 1

同样,如果我从 / 提供图像,我可以让它从静态文件夹中提供图像。但是我不能同时提供来自 / 的处理程序和来自 / 的静态/图像。如果我将图像放在 /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)
}

处理程序/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
4

2 回答 2

10

我终于想通了...

您可以将模板文件夹保留在主文件夹中并从那里嵌入它们。然后您需要将 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",...
...
于 2021-05-02T13:47:06.147 回答
2

目前在 Go 1.17 中,embed 不支持子文件夹/包,请参阅https://github.com/golang/go/issues/41191#issuecomment-686616556

于 2021-11-11T07:49:32.570 回答