Go template.ExecuteTemplate包含html
我遵循了本教程:并根据我的需要对其进行了轻微修改。问题是我想在模板中支持HTML。我意识到这是一种安全风险,但目前还不担心 页面呈现的结果:Go template.ExecuteTemplate包含html,go,go-templates,Go,Go Templates,我遵循了本教程:并根据我的需要对其进行了轻微修改。问题是我想在模板中支持HTML。我意识到这是一种安全风险,但目前还不担心 页面呈现的结果: <h1>this<strong>is</strong>a test</h1> 我想要的HTML数据存储在Page.Body中。这是类型[]byte,这意味着我不能(或者可以?)运行html/template.html(Page.Body),因为该函数需要一个字符串 我有一个预渲染模板的程序: var (
<h1>this<strong>is</strong>a test</h1>
我想要的HTML数据存储在Page.Body
中。这是类型[]byte
,这意味着我不能(或者可以?)运行html/template.html(Page.Body)
,因为该函数需要一个字符串
我有一个预渲染模板的程序:
var (
templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)
实际的ExecuteTemplate
如下所示:
err := templates.ExecuteTemplate(w, tmpl+".html", p)
str := string(page.Body)
其中w是http.ResponseWriterw,tmpl是tmpl字符串
,p是p*Page
最后,我的'view.html'
(模板)如下所示:
<h1>{{.Title}}</h1>
<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
<div>{{printf "%s" .Body}}</div>
{{.Title}
[]
{{printf“%s”.Body}
我尝试过的事情:
{{printf“%s”.Body | html}}
没有任何作用
- 我已经包括了
github.com/russross/blackfriday
(Markdown处理器),并运行了p.Body=blackfriday.markdowncomon(p.Body)
,它正确地将Markdown转换为HTML,但HTML仍然作为实体输出
- 编辑:我尝试了以下代码(我不知道为什么格式会出错),但它仍然输出完全相同的结果
var s template.HTML
s=template.HTML(p.Body)
p.Body=[]字节
非常感谢您的指导。如果我感到困惑,请提问,我可以修改我的问题。为什么不将[]字节转换为字符串?您可以这样做:
err := templates.ExecuteTemplate(w, tmpl+".html", p)
str := string(page.Body)
将[]字节
或字符串
转换为类型template.HTML
(有文档记录)
然后,在模板中,只需:
{{.Body}}
它将被打印而不会转义
编辑
为了能够在页面正文中包含HTML,您需要更改页面
类型声明:
type Page struct {
Title string
Body template.HTML
}
然后分配给它。查看类型。它可以用来封装已知的HTML安全片段(如Markdown的输出)。“html/template”包不会转义此类型
type Page struct {
Title string
Body template.HTML
}
page := &Page{
Title: "Example",
Body: template.HTML(blackfriday.MarkdownCommon([]byte("foo bar")),
}
我通常编写自己的func Markdown(text string)html.Template
方法,用适当的配置调用blackfriday并进行一些类型转换。另一种选择可能是在模板解析器中注册一个“html”func,它允许您通过执行类似于{{html.MySafeStr}}
的操作来输出任何值而不进行任何转义。代码可能如下所示:
var tmpl = template.Must(template.New("").Funcs(template.FuncMap{
"html": func(value interface{}) template.HTML {
return template.HTML(fmt.Sprint(value))
},
}).ParseFiles("file1.html", "file2.html"))
我使用Beego和React.js,花了几个小时试图让JSX解析器运行。结果是html/模板去掉了注释,尤其是js doc block/**@jsx React.DOM*/
通过创建一个特殊的方法将注释输入为JS并在模板中调用它,解决了这个问题
// Create a method in your controller (I'm using Beego)
func jsxdoc()(out template.JS) {
return template.JS(`/** @jsx React.DOM */`)
}
// Add method to your function map available to views
beego.AddFuncMap("jsxdoc", jsxdoc)
// In template
<script type="text/jsx">
{{ jsxdoc }}
var CommentBox = React.createClass({
render: function() {
return (
<div class="commentBox">
Hello, world! I am a CommentBox.
</div>
);
}
});
React.renderComponent(
<CommentBox />,
document.getElementById('content')
);
</script>
//在控制器中创建一个方法(我正在使用Beego)
func jsxdoc()(out template.JS){
返回template.JS(`/**@jsx React.DOM*/`)
}
//将方法添加到视图可用的函数映射中
AddFuncMap(“jsxdoc”,jsxdoc)
//模板中
{{jsxdoc}}
var CommentBox=React.createClass({
render:function(){
返回(
你好,世界!我是一个评论箱。
);
}
});
React.renderComponent(
,
document.getElementById('content')
);
有关向模板传递HTML的说明和更简单的方法,请参阅
只需通过go创建HTML字符串并将其传递到模板中,例如:
Sout := ""
.
.
Sout += fmt.Sprintf(`<tr><td>%s<td align=center>%.2f<td>%s<td>%s<td>%s<td>%s<td align=center>%d<td align=center>%d
<td align=center>%d`, AccountID, amount, remissiondetails, created, begins, ends,
freePDFs, freeinformants, freeSDQs)
.
.
render(w, "templates/Waivers.html", map[string]interface{}{ "Body":template.HTML(Sout), })
Sout:=“”
.
.
Sout+=fmt.Sprintf(`%s%.2f%s%s%s%s%d%d
%d`、帐户ID、金额、减免明细、创建、开始、结束、,
免费PDF、免费线人、免费DQ)
.
.
render(w,“templates/averages.html”,map[string]接口{}{“Body”:template.html(Sout),})
我为模板创建了一个自定义函数,如下所示:
func noescape(str string) template.HTML {
return template.HTML(str)
}
var fn = template.FuncMap{
"noescape": noescape,
}
然后在模板上:
{{ noescape $x.Body }}
这是一种不需要对现有结构进行任何更改的方法,并且只需对模板进行非常小的附加更改:
var (
templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)
更改这些行:
var (
templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)
为此(包括一个funcmap,其中包含一个将输出未转义HTML的函数):
然后只需从以下内容更改模板HTML:
<div>{{printf "%s" .Body}}</div>
{{printf“%s”.Body}
为此(使用新功能):
{{.Body|safeHTML}
容易多了 在我的例子中(我用活动的列表填充视图结构
),我必须将属性消息字符串
更改为消息模板.HTML
。然后,当设置属性值时,我可以调用activity.Message=template.HTML(“HTML”)
我尝试过,问题是模板。ExecuteTemplate
需要一个指向页面的指针,该指针要求它是[]字节
我尝试了完全按照您所说的做,并收到以下错误:无法使用字符串(p.Body)(type string)作为赋值中的[]字节类型
。同样,将我的结构更改为使用字符串而不是[]字节会在将内容保存到文件时导致其他问题。这不起作用。我收到以下消息:无法将“html/template.html(p.Body)(type“html/template.html”)作为[]类型使用分配中的字节
不要只是复制粘贴并说它不起作用。显然,您需要更改正文字段的类型,以便能够将template.HTML类型的内容分配给它。请参阅我昨晚在发布评论后对我的问题所做的编辑。我确实更改了正文的类型,但我仍然看到了确切的sam我添加了一个名为“noescape”的函数,该函数将字符串转换为template.HTML
,然后在管道中将printf
转换为字符串。这个函数非常神奇。我花了几天的时间对我的模板感到非常生气,因为我通过了它
<div>{{ .Body | safeHTML }}</div>