Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get rid of ZgotmplZ from html/template in Golang?

I'm using Golang in backend. When I render the html using html/templates I'm getting ZgotmplZ for URL's.

{{if .UserData.GitURL}}
<li>
  <a href="{{.UserData.GitURL}}">
    <i class="icon fa fa-github"></i>
  </a>
</li>
{{end}}

I'm using string for GitURL in server side. This URL is https. When I looked for solutions some blog suggested to use safeURL. So I tried,

{{if .UserData.GitURL}}
<li>
  <a href="{{.UserData.GitURL | safeURL}}">
    <i class="icon fa fa-github"></i>
  </a>
</li>
{{end}}

But code didn't compile.

Could someone help me with this? Any suggestion would be really helpful.

like image 363
Dany Avatar asked Apr 03 '16 07:04

Dany


1 Answers

ZgotmplZ is a special value indicating your input was invalid. Quoting from the doc of html/template:

"ZgotmplZ" is a special value that indicates that unsafe content reached a
CSS or URL context at runtime. The output of the example will be
   <img src="#ZgotmplZ">
If the data comes from a trusted source, use content types to exempt it
from filtering: URL(`javascript:...`).

If you want to substitute a valid url text, nothing special like like safeURL function is needed. If your template execution results in a value like "#ZgotmplZ", that means the URL you wanted to insert is invalid.

See this example:

t := template.Must(template.New("").Parse(`<a href="{{.}}"></a>` + "\n"))
t.Execute(os.Stdout, "http://google.com")
t.Execute(os.Stdout, "badhttp://google.com")

Output:

<a href="http://google.com"></a>
<a href="#ZgotmplZ"></a>

You may use a value of type template.URL if you want to use a URL as-is without escaping. Note that in this case the provided value will be used as-is even if it is not a valid URL.

safeURL is not some kind of magic or predeclared function that you may use in templates. But you may register your own custom function which returns a string url parameter as a value of type template.URL:

t2 := template.Must(template.New("").Funcs(template.FuncMap{
    "safeURL": func(u string) template.URL { return template.URL(u) },
}).Parse(`<a href="{{. | safeURL}}"></a>` + "\n"))
t2.Execute(os.Stdout, "http://google.com")
t2.Execute(os.Stdout, "badhttp://google.com")

Output:

<a href="http://google.com"></a>
<a href="badhttp://google.com"></a>

Note: If you are able to pass in a template.URL value directly to the template execution, you do not need to register and use a safeURL() custom function:

t3 := template.Must(template.New("").Parse(`<a href="{{.}}"></a>` + "\n"))
t3.Execute(os.Stdout, template.URL("http://google.com"))
t3.Execute(os.Stdout, template.URL("badhttp://google.com"))

Output:

<a href="http://google.com"></a>
<a href="badhttp://google.com"></a>

Try these on the Go Playground.

like image 59
icza Avatar answered Sep 30 '22 21:09

icza