Перейти шаблон.ExecuteTemplate включают в себя 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
что означает, что я не могу (или могу?) run 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 w http.ResponseWriter
, tmpl является tmpl string
, а p 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 по-прежнему выводится как сущности. -
EDIT: я попытался следующий бит кода (я не знаю, почему формат испорчен), и он по-прежнему выводит точное тот же.
var s template.HTML
s = template.HTML(p.Body)
p.Body = []byte(s)
любое руководство очень ценится. Если я запутываюсь, пожалуйста, спросите, и я могу изменить свой вопрос.
7 ответов
преобразовать []byte
или string
типа template.HTML
(документально здесь)
p.Body = template.HTML(s) // where s is a string or []byte
затем, в вашем шаблоне, просто:
{{.Body}}
он будет напечатан без побега.
редактировать
для того, чтобы иметь возможность включать HTML в тело вашей страницы, вам нужно изменить Page
тип объявления:
type Page struct {
Title string
Body template.HTML
}
затем присвоить его.
посмотри шаблон.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"))
Я создал пользовательскую функцию для шаблона следующим образом:
func noescape(str string) template.HTML {
return template.HTML(str)
}
var fn = template.FuncMap{
"noescape": noescape,
}
затем на вашем шаблоне:
{{ noescape $x.Body }}
Я использую Beego и React.js и боролись часами, пытаясь запустить парсер JSX. Оказывается, html / шаблон удаляет комментарии, особенно блок JS doc / * * @JSX React.ДОМ./*
обошел его, создав специальный метод для ввода комментария как 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>
вот подход, который не требует каких-либо изменений в ваших существующих структурах, и очень минимальное, аддитивное изменение ваших шаблонов:
изменить эти строчки:
var (
templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)
к этому (включите funcmap с функцией, которая будет выводить не-экранированный 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>
гораздо проще!
для уточнения и гораздо более простого способа передачи HTML в шаблон см.
https://groups.google.com/forum#!тема/голанг-орехи/8L4eDkr5Q84
просто создайте строку HTML через go и передайте ее в свой шаблон, например:
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), })