I have a struct that has a url.URL
value as one of its (many) fields. I'm trying to pass an instance of that struct to an html/template
and have it render those fields, including the URL, in a sensible way.
Consider this example code:
package main
import (
"html/template"
"net/url"
"os"
)
var tmpl *template.Template = template.Must(
template.New("").Parse(`<a href="{{ .URL }}">{{ .Text }}</a>` + "
"),
)
type pointer struct {
Text string
URL *url.URL // pointer, which is rendered sensibly
}
type value struct {
Text string
URL url.URL // value, which is not rendered sensibly
}
func main() {
u := url.URL{Scheme: "https", Host: "google.com", Path: "/path"}
pointer := pointer{Text: "pointer", URL: &u}
value := value{Text: "value", URL: u}
tmpl.Execute(os.Stdout, pointer)
tmpl.Execute(os.Stdout, value)
}
On my machine (go 1.9.1), this outputs:
<a href="https://google.com/path">pointer</a>
<a href="%7bhttps%20%20%3cnil%3e%20google.com%20/path%20%20false%20%20%7d">value</a>
On the playground, this outputs:
<a href="https://google.com/path">pointer</a>
<a href="
** Signal 11 from untrusted code: pc=630b0008b020
Program exited.
What's the best way to have html/template
render a url.URL
value that's a field of a passed-struct “normally”?
(Ideally I'd only change the template, or possibly use something in a FuncMap
. I'd also ideally like to avoid either having to create a bunch of almost-identical structs that have *url.URL
s instead of url.URL
s, or having to fill a map with the struct's fields and pass that to the template.)