为什么我在我的Go HTML模板输出中看到ZgotmplZ?

huangapple go评论103阅读模式
英文:

Why am I seeing ZgotmplZ in my Go HTML template output?

问题

当我调用一个Go模板函数来输出HTML时,它显示为ZgotmplZ

示例代码:

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

package main

import (
    "html/template"
    "os"
)

func main() {
    funcMap := template.FuncMap{
        "printSelected": func(s string) string {
            if s == "test" {
                return `selected="selected"`
            }
            return ""
        },

        "safe": func(s string) template.HTML {
            return template.HTML(s)
        },
    }
    template.Must(template.New("Template").Funcs(funcMap).Parse(`
    <option {{ printSelected "test" }} {{ printSelected "test" | safe }}>test</option>
    `)).Execute(os.Stdout, nil)

}

输出:

<option ZgotmplZ ZgotmplZ>test</option>
英文:

When I'm calling a Go template function to output HTML, it displays ZgotmplZ.

Sample code:

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

package main

import (
	&quot;html/template&quot;
	&quot;os&quot;
)

func main() {
	funcMap := template.FuncMap{
		&quot;printSelected&quot;: func(s string) string {
			if s == &quot;test&quot; {
				return `selected=&quot;selected&quot;`
			}
			return &quot;&quot;
		},

		&quot;safe&quot;: func(s string) template.HTML {
			return template.HTML(s)
		},
	}
	template.Must(template.New(&quot;Template&quot;).Funcs(funcMap).Parse(`
	&lt;option {{ printSelected &quot;test&quot; }} {{ printSelected &quot;test&quot; | safe }} &gt;test&lt;/option&gt;
	`)).Execute(os.Stdout, nil)

}

Output:

&lt;option ZgotmplZ ZgotmplZ &gt;test&lt;/option&gt;

答案1

得分: 38

"ZgotmplZ"是一个特殊的值,表示在运行时,不安全的内容达到了CSS或URL上下文。示例的输出将是:

 &lt;img src=&quot;#ZgotmplZ&quot;&gt;

您可以向模板的funcMap中添加一个safe和attr函数:

package main

import (
    &quot;html/template&quot;
    &quot;os&quot;
)

func main() {
    funcMap := template.FuncMap{
	    &quot;attr&quot;:func(s string) template.HTMLAttr{
		    return template.HTMLAttr(s)
	    },
	    &quot;safe&quot;: func(s string) template.HTML {
		    return template.HTML(s)
	     },
    }

    template.Must(template.New(&quot;Template&quot;).Funcs(funcMap).Parse(`
    &lt;option {{  .attr |attr }} &gt;test&lt;/option&gt;
        {{.html|safe}}
     `)).Execute(os.Stdout,   map[string]string{&quot;attr&quot;:`selected=&quot;selected&quot;`,&quot;html&quot;:`&lt;option selected=&quot;selected&quot;&gt;option&lt;/option&gt;`})
}

输出将如下所示:

&lt;option selected=&quot;selected&quot; &gt;test&lt;/option&gt;
&lt;option selected=&quot;selected&quot;&gt;option&lt;/option&gt;

您可能还想定义一些其他函数,可以将字符串转换为template.CSS、template.JS、template.JSStr、template.URL等。

英文:

"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:

 &lt;img src=&quot;#ZgotmplZ&quot;&gt;

You can add a safe and attr function to the template funcMap:

package main

import (
    &quot;html/template&quot;
    &quot;os&quot;
)

func main() {
    funcMap := template.FuncMap{
	    &quot;attr&quot;:func(s string) template.HTMLAttr{
		    return template.HTMLAttr(s)
	    },
	    &quot;safe&quot;: func(s string) template.HTML {
		    return template.HTML(s)
	     },
    }

    template.Must(template.New(&quot;Template&quot;).Funcs(funcMap).Parse(`
    &lt;option {{  .attr |attr }} &gt;test&lt;/option&gt;
        {{.html|safe}}
     `)).Execute(os.Stdout,   map[string]string{&quot;attr&quot;:`selected=&quot;selected&quot;`,&quot;html&quot;:`&lt;option selected=&quot;selected&quot;&gt;option&lt;/option&gt;`})
}

The output will look like:

&lt;option selected=&quot;selected&quot; &gt;test&lt;/option&gt;
&lt;option selected=&quot;selected&quot;&gt;option&lt;/option&gt;

You may want to define some other functions which can convert string to template.CSS, template.JS, template.JSStr, template.URL etc.

答案2

得分: 9

我在&lt;img src=&quot;{{myfunction}}&quot;&gt;中遇到了类似的问题,其中myfunction返回编码后的图像。

最后,当函数返回template.URL(mystring)而不是字符串时,我解决了这个问题。

英文:

I had similar problem with &lt;img src=&quot;{{myfunction}}&quot;&gt; where myfunction return encoded image.

Finally I solved it when instead of string function return template.URL(mystring).

答案3

得分: 4

你正在尝试在模板/HTML认为不安全的位置输出HTML(例如,在HTML元素内部,像这样:

&lt;option {{ printSelected }}&gt;

我找不到任何方法来说服它是安全的(包括返回template.HTML而不是字符串);我找到的唯一替代方法是重写模板,在这个例子中使用布尔输出:

&lt;option {{ if printSelected }}selected{{ end }}&gt;
英文:

You are trying to output HTML in a place where template/html thinks is unsafe (for example, inside an HTML element, like this:

&lt;option {{ printSelected }}&gt;

I cannot find any way to convince it it is safe (including returning template.HTML instead of string); the only alternative I have found is to rewrite the template, in this example use a bool output instead:

&lt;option {{ if printSelected }}selected{{ end }}&gt;

答案4

得分: 4

&lt;div&gt;test div&lt;/div&gt;
&lt;option selected=&quot;selected&quot; style=&quot;font-size: 15px&quot;&gt;test&lt;/option&gt;
&lt;script&gt;console.log(&quot;hello world&quot;)&lt;/script&gt;
&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg&quot;&gt;
英文:
package main

import (
	&quot;html/template&quot;
	&quot;os&quot;
)

type T struct {
	HTML template.HTML
	ATTR template.HTMLAttr
	URL  template.URL
	JS   template.JS
	CSS  template.CSS
}

func main() {

	data := T{
		HTML: `&lt;div&gt;test div&lt;/div&gt;`,
		ATTR: `selected=&quot;selected&quot;`,
		URL:  `https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg`,
		CSS:  `font-size: 15px`,
		JS:   `console.log(&quot;hello world&quot;)`,
	}

	template.Must(template.New(&quot;Template&quot;).Parse(`
		{{.HTML}}
		&lt;option {{.ATTR}} style=&quot;{{.CSS}}&quot;&gt;test&lt;/option&gt;
		&lt;script&gt;{{.JS}}&lt;/script&gt;
		&lt;img src=&quot;{{.URL}}&quot;&gt;
	`)).Execute(os.Stdout, data)
}

output

&lt;div&gt;test div&lt;/div&gt;
&lt;option selected=&quot;selected&quot; style=&quot;font-size: 15px&quot;&gt;test&lt;/option&gt;
&lt;script&gt;console.log(&quot;hello world&quot;)&lt;/script&gt;
&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/5/53/Google_%22G%22_Logo.svg&quot;&gt;

playground Example

答案5

得分: 3

最简单的方法:

import "html/template"
yourhref = template.URL(yourhref)
英文:

easiest way:

import &quot;html/template&quot;
yourhref = template.URL(yourhref)

答案6

得分: 1

你应该将字符串包装在HTMLAttr中,它是为在尖括号之间注入的文本而设计的。根据文档:

https://golang.org/pkg/html/template/#HTMLAttr

> HTMLAttr封装了来自可信源的HTML属性,例如,&#160;dir=&quot;ltr&quot;
>
> 使用此类型存在安全风险:封装的内容应来自可信源,因为它将原样包含在模板输出中。
>
>type HTMLAttr string

英文:

You should wrap the string in an HTMLAttr, which was designed for text that gets injected in between angle brackets. Per the documentation:

https://golang.org/pkg/html/template/#HTMLAttr

> HTMLAttr encapsulates an HTML attribute from a trusted source, for example, &#160;dir=&quot;ltr&quot;.
>
> Use of this type presents a security risk: the encapsulated content should come from a trusted source, as it will be included verbatim in the template output.
>
>type HTMLAttr string

答案7

得分: 0

我试图将frontmatter中的图像插入到我的模板中,但一直出现相同的错误。我通过以下方式解决了这个问题:

{{ if isset .Params "image" }}
    {{ $myVar := print .Params.image }}
    <img src="{{ $myVar }}">
{{ end }}

请注意,我首先将.Params.image保存为一个变量,然后将其插入到我的src中。

英文:

I was trying to insert an image from frontmatter into my template but kept getting the same error. I solved it thus:

{{ if isset .Params &quot;image&quot; }}
    {{ $myVar := print .Params.image }}
    &lt;img src=&quot;{{ $myVar }}&quot;&gt;
{{ end }}

Notice that I first save the .Params.image as a variable, and then insert it as my src.

huangapple
  • 本文由 发表于 2013年2月8日 11:51:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/14765395.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定