Skip to content

text/template: template.New(name).ParseFiles(file) not behaving as expected #65996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
udf2457 opened this issue Feb 28, 2024 · 4 comments
Closed

Comments

@udf2457
Copy link

udf2457 commented Feb 28, 2024

Go version

1.22

Output of go env in your module/workspace:

Not applicable for this

What did you do?

t, err := template.New(name).ParseFiles(file)
if err != nil {
  log.Error("failed to load template", "err", err.Error())
  os.Exit(1)
}

then elsewhere ...

t.Execute(...)

What did you see happen?

On Execute() an error was raised:

name: \"name\" is an incomplete or empty template"

What did you expect to see?

Execute() should execute as expected.

Instead, I had to change template.New(name).ParseFiles(file) to template.ParseFiles(file)

I therefore suggest:

  1. The preferred option would be chaining template.New(name).ParseFiles(file) works, as reasonably expected
  2. It errors out if chained

The present situation is unacceptable because you do not discover the problem until Execute() time and when you do, the error message is not helpful in diagnosing the cause.

@AlexanderYastrebov
Copy link
Contributor

AlexanderYastrebov commented Feb 29, 2024

It works when name == file (t, err := template.New("test.tmpl").ParseFiles("test.tmpl")) and fails when not (t, err := template.New("test").ParseFiles("test.tmpl"))

The documentation https://pkg.go.dev/text/template#Template.ParseFiles has somewhat vague explanation of the behaviour.

@AlexanderYastrebov
Copy link
Contributor

See previous #11247

@AlexanderYastrebov
Copy link
Contributor

Since this works (as documented):

func main() {
	t, err := template.New("whatever").ParseFiles("test.tmpl")
	if err != nil {
		log.Fatalf("Failed to load template: %v", err)
	}

	err = t.ExecuteTemplate(os.Stdout, "test.tmpl", nil)
	if err != nil {
		log.Fatalf("Failed to execute template: %v", err)
	}
}

it might be impossible to change the behaviour of template.New("foo").ParseFiles("bar") to return error earlier due to backwards compatibility.

@seankhliao
Copy link
Member

given:

Since the templates created by ParseFiles are named by the base names of the argument files,

I think this is unambiguously working as intended.

it "works" when the name matches simply because it's overwritten.
note that it's also possible to do New().Parse().ParseFiles()

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Feb 29, 2024
@golang golang locked and limited conversation to collaborators Feb 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants