私はこのチュートリアルに従いました: 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は_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プロセッサ)を含め、MarkdownをHTMLに正しく変換するp.Body = blackfriday.MarkdownCommon(p.Body)
を実行しましたが、HTMLはエンティティとして出力されます。編集:次のコードを試してみましたが(フォーマットがめちゃくちゃになっている理由がわかりません)、それでもまったく同じものが出力されます。
_var s template.HTML
_ s = template.HTML(p.Body)
p.Body = []byte(s)
どんなガイダンスも大歓迎です。混乱している場合は質問してください。質問を変更できます。
[]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
}
次に、それに割り当てます。
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")),
}
_
私は通常、適切な構成でblackfridayを呼び出し、いくつかの型変換を行う独自のfunc Markdown(text string) html.Template
メソッドを記述します。別の方法としては、テンプレートパーサーに「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 }}
これは、既存の構造体を変更する必要のないアプローチと、テンプレートへの最小限の追加変更です。
これらの行を変更します。
var (
templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)
これに(エスケープされていないHTMLを出力する関数を含むfuncmapを含めます):
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>
はるかに簡単です!
私はBeegoとReact.jsを使用していて、JSXパーサーを実行するために何時間も戦いました。 html/templateはコメント、特にjs docブロック/ ** @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>
説明と、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), })
私の場合(ビューstruct
にActivity
のリストを入力している場合)、プロパティ_Message string
_を_Message template.HTML
_に変更する必要がありました。次に、プロパティ値を設定するときに、activity.Message = template.HTML("The <b>HTML</b>")
を呼び出すことができます。