Перейти: Указание имен файлов шаблонов для шаблона .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/Template/foo.tmpl" ) и другие, но ничего не работает для обоих случаев. Единичные тесты не работают либо bar.go, либо baz.go (или оба).

Где должен быть размещен файл шаблона и как я должен называть ParseFiles так, чтобы он всегда мог найти файл шаблона независимо от того, в какой директории я вызываю go test?

Ответ 1

Полезный совет:

Используйте 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 содержала только шаблоны для представления и не переходила к файлам.

Далее, чтобы облегчить жизнь, запустите только файлы из корневого каталога проекта. Это поможет сделать путь к файлу согласованным по всем файлам go, вложенным в подкаталоги. Относительные пути к файлам начинаются с текущего рабочего каталога, из которого вызывается программа.

Пример отображения изменения в текущем рабочем каталоге

[email protected]:~/go/src/test$ go run showPath.go
/home/user/go/src/test/template/index.gtpl
[email protected]:~/go/src/test$ cd newFolder/
[email protected]:~/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")
)