问题 Go:为template.ParseFiles指定模板文件名


我当前的目录结构如下所示:

App
  - Template
    - foo.go
    - foo.tmpl
  - Model
    - bar.go
  - Another
    - Directory
      - baz.go

文件 foo.go 使用 ParseFiles 在期间读取模板文件 init

import "text/template"

var qTemplate *template.Template

func init() {
  qTemplate = template.Must(template.New("temp").ParseFiles("foo.tmpl"))
}

...

单元测试 foo.go 按预期工作。但是,我现在正在尝试运行单元测试 bar.go 和 baz.go 这两个都导入 foo.go 我试图打开时感到恐慌 foo.tmpl

/App/Model$ go test    
panic: open foo.tmpl: no such file or directory

/App/Another/Directory$ go test    
panic: open foo.tmpl: no such file or directory

我已经尝试将模板名称指定为相对目录(“./foo.tmpl”),完整目录(“〜/ go / src / github.com / App / Template / foo.tmpl”),App相对目录(“/App/Template/foo.tmpl”)和其他人,但似乎没有任何东西适用于这两种情况。单元测试失败了 bar.go 要么 baz.go (或两者)。

我的模板文件应该放在哪里以及我应该如何调用 ParseFiles 这样无论我调用哪个目录,它总能找到模板文件 go test 从?


7371
2017-09-26 17:51


起源

你能发一个明确的例子说明你想要做什么吗?我试过了 ParseFiles("../Template/foo.tmpl") 从 Model 它工作得很好。 - creack
但如果我试着跑 go test 在更深的目录中它不再起作用。从我的能力来看, go test 总是设置当前的工作目录然后 ParseFiles 使用它作为基本目录来查找模板,而不是相对于调用的文件 ParseFiles。这非常脆弱所以我认为我一定做错了。 - Bill
我已经更新了我的问题,以显示我遇到的问题。 - Bill


答案:


有用的提示:

使用 os.Getwd() 和 filepath.Join() 找到相对文件路径的绝对路径。

// File: showPath.go
package main
import (
        "fmt"
        "path/filepath"
        "os"
)
func main(){
        cwd, _ := os.Getwd()
        fmt.Println( filepath.Join( cwd, "./template/index.gtpl" ) )
}

首先,我建议 template 文件夹仅包含演示文稿的模板,而不包含文件。

接下来,为了简化生活,只运行根项目目录中的文件。这将有助于使嵌套在子目录中的整个文件中的文件路径保持一致。相对文件路径从当前工作目录的位置开始,该目录是调用程序的位置。

显示当前工作目录中的更改的示例

user@user:~/go/src/test$ go run showPath.go
/home/user/go/src/test/template/index.gtpl
user@user:~/go/src/test$ cd newFolder/
user@user:~/go/src/test/newFolder$ go run ../showPath.go 
/home/user/go/src/test/newFolder/template/index.gtpl

对于测试文件,您可以通过提供文件名来运行单个测试文件。

go test foo/foo_test.go

最后,使用基本路径和 path/filepath 打包以形成文件路径。

例:

var (
  basePath = "./public"
  templatePath = filepath.Join(basePath, "template")
  indexFile = filepath.Join(templatePath, "index.gtpl")
) 

12
2017-12-06 05:55