html/template の解決策: "your-template.tmpl"は未定義です


TL;DR



最初に、テンプレートを実行するときに相対ファイルパスを使用していると思いましたが、実際にはベースファイル名 (ディレクトリなし) であるテンプレート名を使用しているため、間違っていました.

長い説明



すばらしい Golang wiki page assignment に従っている間、テンプレート ファイルをサブディレクトリに配置して機能させるのに苦労しました.

ここにいる場合は、次のディレクトリのいくつかがある可能性があります.

├── IAmNew.txt
├── TestPage.txt
├── go.mod
├── tmpl
│   ├── page-edit.html
│   └── page-view.html
└── wiki.go


そして、これに似たコードがあります:

var templates = template.Must(template.ParseGlob("./tmpl/*.html"))


あるいは、ParseFiles を使用し、代わりにファイルのリストを持っているかもしれません:

var templates = template.Must(template.ParseGlob("tmpl/page-view.html", "tmpl/page-edit.html"))


⚠️ テンプレートの間違った実行方法

err := templates.ExecuteTemplate(w, "tmpl/"+tmpl+".html", p)


✅ ディレクトリプレフィックスを削除したところ、機能しました

err := templates.ExecuteTemplate(w, tmpl+".html", p)


ドキュメント自体からの説明



ParseFiles は、新しいテンプレートを作成し、名前付きファイルからテンプレート定義を解析します.返されるテンプレートの名前には、最初のファイルの (ベース) 名と (解析された) 内容が含まれます.少なくとも 1 つのファイルが必要です.
エラーが発生した場合、解析は停止し、返される *Template は nil です.

また、別の考えられる理由は



異なるディレクトリにある同じ名前の複数のファイルを解析する場合、最後に言及されたファイルが結果になります.たとえば、ParseFiles("a/foo", "b/foo") は "b/foo"を "foo"という名前のテンプレートとして格納しますが、"a/foo"は使用できません.