DEV Community

hzoltan
hzoltan

Posted on

Solution to html/template: "your-template.tmpl" is undefined

TL;DR

First I thought when I execute a template I'm using relative filepath, but I was wrong because it actually using template name, which is the base file name (without the directory).

Longer explanation

While following the awesome Golang wiki page assignment, I had hard time with putting the template files into a subdirectory and make them work.

If you are here, you might have some of the following directory:

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

And you have something similar code to this:

var templates = template.Must(template.ParseGlob("./tmpl/*.html"))
Enter fullscreen mode Exit fullscreen mode

or maybe you used the ParseFiles and have a list of files instead:

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

⚠️ Wrong way of executing templates

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

✅ I removed the directory prefix and it worked

err := templates.ExecuteTemplate(w, tmpl+".html", p)
Enter fullscreen mode Exit fullscreen mode

Explanation from the documentation itself

ParseFiles creates a new Template and parses the template definitions from the named files. The returned template's name will have the (base) name and (parsed) contents of the first file. There must be at least one file.
If an error occurs, parsing stops and the returned *Template is nil.

Also another possible reason could be

When parsing multiple files with the same name in different directories, the last one mentioned will be the one that results. For instance, ParseFiles("a/foo", "b/foo") stores "b/foo" as the template named "foo", while "a/foo" is unavailable.

Discussion (0)