web-dev-qa-db-ja.com

Go.template.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_型です。これは、関数が文字列を期待しているため、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)

どんなガイダンスも大歓迎です。混乱している場合は質問してください。質問を変更できます。

26
Peter

[]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
}

次に、それに割り当てます。

49
thwd

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"))
_
16
tux21b

次のように、テンプレートのカスタム関数を作成しました。

func noescape(str string) template.HTML {
    return template.HTML(str)
}

var fn = template.FuncMap{
    "noescape": noescape,
}

次に、テンプレートで:

{{ noescape $x.Body }}
8
majidarif

これは、既存の構造体を変更する必要のないアプローチと、テンプレートへの最小限の追加変更です。

これらの行を変更します。

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>

はるかに簡単です!

1
Astockwell

私は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>
1
user2363571

説明と、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), })
0
user2099484

私の場合(ビューstructActivityのリストを入力している場合)、プロパティ_Message string_を_Message template.HTML_に変更する必要がありました。次に、プロパティ値を設定するときに、activity.Message = template.HTML("The <b>HTML</b>")を呼び出すことができます。

0
crmepham