英文:
Go template.ExecuteTemplate include html
问题
我已经按照你给出的链接(http://golang.org/doc/articles/wiki/final.go)进行了教程的跟随,并对其进行了一些微小的修改以满足我的需求。问题是,我想在模板中支持HTML。我意识到这可能存在安全风险,但目前并不是我的关注点。
页面渲染的结果如下:
<h1>this<strong>is</strong>a test</h1>
让我稍微解释一下代码:
type Page struct {
Title string
Body []byte
}
我想要包含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)
其中,w
是http.ResponseWriter
,tmpl
是string
,p
是*Page
。
最后,我的'view.html'
(模板)如下所示:
<h1>{{.Title}}</h1>
<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
<div>{{printf "%s" .Body}}</div>
我尝试过的方法:
-
{{printf "%s" .Body | html}}
没有起作用 -
我已经包含了
github.com/russross/blackfriday
(Markdown处理器),并运行了p.Body = blackfriday.MarkdownCommon(p.Body)
,它可以正确地将Markdown转换为HTML,但输出的HTML仍然是实体。 -
**编辑:**我尝试了下面这段代码(我不知道为什么格式乱了),但输出结果仍然完全相同。
var s template.HTML
s = template.HTML(p.Body)
p.Body = []byte(s)
非常感谢您的指导。如果我表达不清楚,请提问,我可以修改我的问题。
英文:
I have followed this tutorial: http://golang.org/doc/articles/wiki/final.go and have slightly modified it for my needs/wants. The problem is I would like to support HTML in the templates. I realize this is a security risk but it's not a concern at the moment.
The result of a page render:
<h1>this<strong>is</strong>a test</h1>
Let me explain a little bit of the code:
type Page struct {
Title string
Body []byte
}
The data I would like to have HTML is stored in Page.Body
. This is type []byte
which means I can't (or can I?) run html/template.HTML(Page.Body)
as that function expects a string.
I have this which pre-renders the templates:
var (
templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)
And the actual ExecuteTemplate
looks like this:
err := templates.ExecuteTemplate(w, tmpl+".html", p)
Where w is w http.ResponseWriter
, tmpl is tmpl string
, and p is p *Page
Finally my 'view.html'
(template) looks like the following:
<h1>{{.Title}}</h1>
<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
<div>{{printf "%s" .Body}}</div>
Things I have tried:
-
{{printf "%s" .Body | html}}
doesn't do anything -
I have included
github.com/russross/blackfriday
(Markdown processor) and have runp.Body = blackfriday.MarkdownCommon(p.Body)
which correctly converts Markdown to HTML, but the HTML is still output as entities. -
EDIT: I have attempted the following bit of code (I don't know why the format is messed up) and it still outputs the exact same.
var s template.HTML
s = template.HTML(p.Body)
p.Body = []byte(s)
Any guidance is greatly appreciated. If I'm being confusing please ask and I can modify my question.
答案1
得分: 78
将你的[]byte
或string
转换为template.HTML
类型(在这里有文档记录)。
p.Body = template.HTML(s) // 其中s是一个字符串或[]byte
然后,在你的模板中,只需:
{{.Body}}
它将被打印而不进行转义。
编辑
为了能够在页面的正文中包含HTML,你需要更改Page
类型的声明:
type Page struct {
Title string
Body template.HTML
}
然后对其进行赋值。
英文:
Convert your []byte
or string
to type template.HTML
(documented here)
p.Body = template.HTML(s) // where s is a string or []byte
Then, in your template, just:
{{.Body}}
It will be printed without escaping.
EDIT
In order to be able to include HTML in you page's body you need to change the Page
type declaration:
type Page struct {
Title string
Body template.HTML
}
then assign to it.
答案2
得分: 22
请看一下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"函数,通过类似{{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"))
英文:
Take a look at the template.HTML type. It can be used to encapsulate a known safe fragment of HTML (like the output from Markdown). The "html/template" package will not escape this this type.
type Page struct {
Title string
Body template.HTML
}
page := &Page{
Title: "Example",
Body: template.HTML(blackfriday.MarkdownCommon([]byte("foo bar")),
}
I usually write my own func Markdown(text string) html.Template
method that calls blackfriday with the appropriate config and does some type conversions. Another alternative might be also to register a "html" func in the template parser, that allows you to output any value without any escaping by doing something like {{html .MySafeStr}}
. The code might look like:
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"))
答案3
得分: 20
我为模板创建了一个自定义函数,如下所示:
func noescape(str string) template.HTML {
return template.HTML(str)
}
var fn = template.FuncMap{
"noescape": noescape,
}
然后在你的模板中使用:
{{ noescape $x.Body }}
英文:
I created a custom function for the template as follows:
func noescape(str string) template.HTML {
return template.HTML(str)
}
var fn = template.FuncMap{
"noescape": noescape,
}
Then on your template:
{{ noescape $x.Body }}
答案4
得分: 3
这是一种不需要对现有结构进行任何更改,并且对模板只需要进行非常小的增量更改的方法:
将这些行代码进行更改:
var (
templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)
更改为以下内容(包括一个使用函数映射的函数,用于输出未转义的HTML):
var templates = template.Must(template.New("main").Funcs(template.FuncMap{
"safeHTML": func(b []byte) template.HTML {
return template.HTML(b)
},
}).ParseFiles("tmpl/edit.html", "tmpl/view.html"))
然后只需将模板中的HTML代码从这个:
<div>{{printf "%s" .Body}}</div>
更改为这个(使用新的函数):
<div>{{ .Body | safeHTML }}</div>
非常简单!
英文:
Here's an approach that doesn't require any changes to your existing structs, and a very minimal, additive change to your templates:
Change these lines:
var (
templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)
to this (include a funcmap with a function that will output un-escaped HTML):
var templates = template.Must(template.New("main").Funcs(template.FuncMap{
"safeHTML": func(b []byte) template.HTML {
return template.HTML(b)
},
}).ParseFiles("tmpl/edit.html", "tmpl/view.html"))
And then just change your template HTML from this:
<div>{{printf "%s" .Body}}</div>
to this (use your new function):
<div>{{ .Body | safeHTML }}</div>
Much easier!
答案5
得分: 1
我正在使用Beego和React.js,并花了几个小时来尝试运行JSX解析器。结果发现html/template会剥离掉注释,特别是js文档块 /** @jsx React.DOM */。
为了解决这个问题,我创建了一个特殊的方法来将注释作为JS代码进行类型转换,并在模板中调用它。
在你的控制器中创建一个方法(我使用的是Beego):
func jsxdoc()(out template.JS) {
return template.JS(`/** @jsx React.DOM */`)
}
将该方法添加到函数映射中,以便在视图中使用:
beego.AddFuncMap("jsxdoc", jsxdoc)
在模板中:
<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>
希望对你有帮助!
英文:
I'm using Beego and React.js and fought for hours trying to get the JSX parser to run. Turns out html/template strips out comments especially the js doc block /** @jsx React.DOM */.
Got around it by creating a special method to Type the comment as JS and calling it from within the template.
// 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>
答案6
得分: 0
为了澄清并更简单地将HTML传递给模板,请参考以下链接:
https://groups.google.com/forum/#!topic/golang-nuts/8L4eDkr5Q84
只需通过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), })
英文:
For clarification and a much simpler way of passing HTML to template, see
https://groups.google.com/forum/#!topic/golang-nuts/8L4eDkr5Q84
Just create your HTML string via go and pass it into your template, e.g.:
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), })
答案7
得分: 0
在我的情况下(我正在使用一个视图struct
来填充一个Activity
列表),我需要将属性Message string
更改为Message template.HTML
。然后,在设置属性值时,我可以调用activity.Message = template.HTML("The <b>HTML</b>")
。
英文:
In my case (where I am populating a view struct
with a list of Activity
), I had to change the property Message string
to Message template.HTML
. Then, when setting the property value I can call activity.Message = template.HTML("The <b>HTML</b>")
.
答案8
得分: -1
为什么不将[]byte
转换为字符串?你可以这样做:
str := string(page.Body)
英文:
Why not convert the []byte
to a string? You can do it like this:
str := string(page.Body)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论