golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.3k stars 17.7k forks source link

text/template: (and html/template) execution option for given errors for missing map keys #6288

Closed gopherbot closed 9 years ago

gopherbot commented 11 years ago

by bjruth:

What steps will reproduce the problem?
If possible, include a link to a program on play.golang.org.

http://play.golang.org/p/zVTrueV2dd

Note the '<no value>' value for lastName.

What is the expected output?

I expect fields used in the template that are missing in the map should return an error
(missing key) rather than render '<no value>'

Please provide any additional information below.

Discussion on golang-nuts:
https://groups.google.com/forum/#!topic/golang-nuts/VPhthY-ocsg

An ideal solution would be a Template.ExecuteStrict method that returns an error rather
than replacing missing keys/fields with '<no value>' in the output (as it does
now). This ensures nothing breaks with programs using Template.Execute in Go 1.x
robpike commented 11 years ago

Comment 1:

It's too close to make the 1.2 deadline but should happen for 1.3.

Labels changed: added priority-later, feature, removed priority-triage.

Owner changed to @robpike.

Status changed to Accepted.

robpike commented 11 years ago

Comment 2:

Not sure what the design should be. It could also be a function on the template that
enables this feature.
gopherbot commented 11 years ago

Comment 3 by bjruth:

One suggestion from the thread was for the template engine to support the Getter
interface on data. So {{.foo}} would resolve to data.Get("foo"). If a error is returned,
it would be returned.
gopherbot commented 11 years ago

Comment 4 by bjruth:

That last statement was not useful :) If and error is returned from data.Get("foo"), it
will be returned on Execute.
gopherbot commented 11 years ago

Comment 5 by bjruth:

A more complete explanation of my first comment: Execute can fall back to using the
Getter interface if data is a struct and does not contain the field. So {{.Foo}} would
resolve to data.Foo if defined and fall back to data.Get("Foo") if implemented. This
enables custom handling in the Get method and the ability to return an error like method
calls. This _could_ remove the need to implement a separate ExecuteStrict for stricter
handling although I believe the default behavior should (eventually) be to return an
error. The Getter support could just be another feature of the template engine.
rsc commented 11 years ago

Comment 6:

Labels changed: added go1.3maybe.

rsc commented 11 years ago

Comment 7:

Labels changed: removed feature.

rsc commented 10 years ago

Comment 8:

Labels changed: added release-none, removed go1.3maybe.

rsc commented 10 years ago

Comment 9:

Labels changed: added repo-main.

gopherbot commented 10 years ago

Comment 10 by jd@tekii.com.ar:

There is a possible workaround this, and that is to define your parameter as an
interface and then size the length to see that you are not getting any, and that means
that you got no result from  your map.
http://play.golang.org/p/Kj7iqnqu1x
robpike commented 10 years ago

Comment 11:

Labels changed: added release-go1.3maybe, removed priority-later, release-none.

rsc commented 10 years ago

Comment 12:

Labels changed: added release-none, suggested, removed release-go1.3maybe.

gopherbot commented 9 years ago

Comment 13 by einthusan@wojka.com:

Hi, I am having the same issue. I guess this didn't make it for Go 1.4 either... really
need a way for template to fail upon missing map keys.
j7b commented 9 years ago

You can implement pretty decent fail and default value behaviors with functions:

https://play.golang.org/p/AC_JYvE2CK

awly commented 9 years ago

@robpike What's the rationale of this string-based approach as opposed to Options field in template.Template? If new options are added you will have to update text/template and html/template anyway. Struct-based implementation would add compile-time safety and feels cleaner.

robpike commented 9 years ago

It's a simpler API this way and html/template will not need to echo every type and constant.