Go – HTML注释不会被渲染

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

Go - HTML comments are not rendered

问题

我正在构建一个Go Web应用程序。我发现渲染的HTML页面上出现了一些异常。我所有的HTML注释<!-- -->突然不再被渲染了。我猜测这是因为我使用的Go版本(刚刚升级到更高的版本),因为在我更新之前一切都正常。

这是我的代码:

<!-- 准备面包屑 -->
<ul class="breadcrumb" data-bind="foreach: viewModel.breadcrumbs">
	<!-- ko if: ($index() + 1) < len(viewModel.breadcrumbs()) -->
	<li>
		<a data-bind="attr: { href: href }">
			<i class="fa fa-home"></i> 
			<span data-bind="text: title"></span>
		</a>
	</li>
	<!-- /ko -->

	<!-- ko if: ($index() + 1) == len(viewModel.breadcrumbs()) -->
	<li class="active" data-bind="text: title"></li>
	<!-- /ko -->
</ul>

这是渲染后的页面源代码:

Go – HTML注释不会被渲染

由于这个问题,我的许多使用无容器控制流语法编写的KnockoutJS代码变得混乱,根本无法工作。

我应该怎么解决这个问题?提前谢谢。

英文:

I'm building go web application. I found some anomaly on the rendered html page. All of my html comments &lt;!-- --&gt; are suddenly not being rendered. My guess it's because the go version I used (just updated to higher version), because it was fine before I updated it.

This is my code:

&lt;!-- prepare the breadcrumbs --&gt;
&lt;ul class=&quot;breadcrumb&quot; data-bind=&quot;foreach: viewModel.breadcrumbs&quot;&gt;
	&lt;!-- ko if: ($index() + 1) &lt; len(viewModel.breadcrumbs()) --&gt;
	&lt;li&gt;
		&lt;a data-bind=&quot;attr: { href: href }&quot;&gt;
			&lt;i class=&quot;fa fa-home&quot;&gt;&lt;/i&gt; 
			&lt;span data-bind=&quot;text: title&quot;&gt;&lt;/span&gt;
		&lt;/a&gt;
	&lt;/li&gt;
	&lt;!-- /ko --&gt;

	&lt;!-- ko if: ($index() + 1) == len(viewModel.breadcrumbs()) --&gt;
	&lt;li class=&quot;active&quot; data-bind=&quot;text: title&quot;&gt;&lt;/li&gt;
	&lt;!-- /ko --&gt;
&lt;/ul&gt;

And this is the rendered page source:

Go – HTML注释不会被渲染

Because of this issue, many of my KnockoutJS codes which are written using containerless control flow syntax goes crazy, it doesn't work at all.

What should I do to solve this? Thanks in advance

答案1

得分: 18

html/template 包中有一种特殊类型:template.HTML。在模板中使用此类型的值时,模板渲染时不会对其进行转义。

因此,你可以将 HTML 注释标记为 template.HTML,这样它们在执行模板时就不会被转义或省略。

一种方法是为模板注册一个自定义函数,该函数可以从模板中调用,接受一个 string 参数并将其作为 template.HTML 返回。你可以将所有的 HTML 注释传递给这个函数,结果就是你的 HTML 注释将保留在输出中。

看下面的例子:

func main() {
    t := template.Must(template.New("").Funcs(template.FuncMap{
        "safe": func(s string) template.HTML { return template.HTML(s) },
    }).Parse(src))
    t.Execute(os.Stdout, nil)
}

const src = `<html><body>
{{safe "<!-- This is a comment -->"}}
<div>Some <b>HTML</b> content</div>
</body></html>`

输出结果(在 Go Playground 上试一试):

<html><body>
<!-- This is a comment -->
<div>Some <b>HTML</b> content</div>
</body></html>

因此,在注册了我们的 safe() 函数之后,将所有的 HTML 注释转换为调用此 safe() 函数的模板操作,并传递原始的 HTML 注释。

将这个:

<!-- Some HTML comment -->

转换为这个:

{{safe "<!-- Some HTML comment -->"}}

或者(根据你的喜好):

{{"<!-- Some HTML comment -->" | safe}}

然后你就可以使用了。

注意: 如果你的 HTML 注释包含引号(&#39;&quot;&#39;),你需要对其进行转义,像这样:

{{safe "<!-- Some \"HTML\" comment -->"}}

注意 #2: 请注意,不要使用条件 HTML 注释,因为那可能会破坏 html/template 包的上下文敏感转义。详细信息请阅读这里

英文:

There is a special type in the html/template package: template.HTML. Values of this type in the template are not escaped when the template is rendered.

So you may "mark" your HTML comments as template.HTML and so they will not be escaped or omitted during executing your template.

One way to do this is to register a custom function for your template, a function which can be called from your template which takes a string argument and returns it as template.HTML. You can "pass" all the HTML comments to this function, and as a result, your HTML comments will be retained in the output.

See this example:

func main() {
	t := template.Must(template.New(&quot;&quot;).Funcs(template.FuncMap{
		&quot;safe&quot;: func(s string) template.HTML { return template.HTML(s) },
	}).Parse(src))
	t.Execute(os.Stdout, nil)
}

const src = `&lt;html&gt;&lt;body&gt;
{{safe &quot;&lt;!-- This is a comment --&gt;&quot;}}
&lt;div&gt;Some &lt;b&gt;HTML&lt;/b&gt; content&lt;/div&gt;
&lt;/body&gt;&lt;/html&gt;`

Output (try it on the Go Playground):

&lt;html&gt;&lt;body&gt;
&lt;!-- This is a comment --&gt;
&lt;div&gt;Some &lt;b&gt;HTML&lt;/b&gt; content&lt;/div&gt;
&lt;/body&gt;&lt;/html&gt;

So basically after registering our safe() function, transform all your HTML comments to a template action calling this safe() function and passing your original HTML comment.

Convert this:

&lt;!-- Some HTML comment --&gt;

To this:

{{safe &quot;&lt;!-- Some HTML comment --&gt;&quot;}}

Or alternatively (whichever you like):

{{&quot;&lt;!-- Some HTML comment --&gt;&quot; | safe}}

And you're good to go.

Note: If your HTML comment contains quotation marks (&#39;&quot;&#39;), you can / have to escape it like this:

{{safe &quot;&lt;!-- Some \&quot;HTML\&quot; comment --&gt;&quot;}}

Note #2: Be aware that you shouldn't use conditional HTML comments as that may break the context sensitive escaping of html/template package. For details read this.

答案2

得分: -1

你可以使用text/template代替html/template,并手动使用内置函数(如htmljs)进行所有的转义操作(https://golang.org/pkg/text/template/#hdr-Functions)。但要注意,这种方法容易出错。

英文:

You can use text/template instead of html/template and do all escaping manually using built-in functions such as html and js (https://golang.org/pkg/text/template/#hdr-Functions). Be aware that this is very error prone though.

huangapple
  • 本文由 发表于 2015年12月18日 11:24:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/34348072.html
匿名

发表评论

匿名网友

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

确定