web-dev-qa-db-ja.com

標準ライブラリを使用してGoでテンプレートをネストすることは可能ですか? (Google App Engine)

Jinjaがpythonランタイムで持っているようなネストされたテンプレートを取得するにはどうすればいいですか? 、Jinja/Django-templatesと同じように、html/template標準ライブラリ。

それが可能性でない場合、私の選択肢は何ですか。口ひげはオプションのように思えますが、html/template状況依存エスケープなど?他にどのような選択肢がありますか?

(環境:Google App Engin、Goランタイムv1、開発-Mac OSxライオン)

読んでくれてありがとう。

80
sri

はい、可能です。 html.Templateは実際にはテンプレートファイルのセットです。このセットで定義済みブロックを実行すると、このセットで定義されている他のすべてのブロックにアクセスできます。

このようなテンプレートセットのマップを独自に作成する場合、基本的にはJinja/Djangoが提供する柔軟性と同じです。唯一の違いは、 html/template パッケージはファイルシステムに直接アクセスできないため、独自にテンプレートを解析および構成する必要があります。

「base.html」から継承する2つの異なるページ(「index.html」および「other.html」)を使用した次の例を考えてみましょう。

// Content of base.html:
{{define "base"}}<html>
  <head>{{template "head" .}}</head>
  <body>{{template "body" .}}</body>
</html>{{end}}

// Content of index.html:
{{define "head"}}<title>index</title>{{end}}
{{define "body"}}index{{end}}

// Content of other.html:
{{define "head"}}<title>other</title>{{end}}
{{define "body"}}other{{end}}

そして、次のテンプレートセットのマップ:

tmpl := make(map[string]*template.Template)
tmpl["index.html"] = template.Must(template.ParseFiles("index.html", "base.html"))
tmpl["other.html"] = template.Must(template.ParseFiles("other.html", "base.html"))

次を呼び出して、「index.html」ページをレンダリングできます。

tmpl["index.html"].Execute("base", data)

呼び出して「other.html」ページをレンダリングできます

tmpl["other.html"].Execute("base", data)

いくつかのトリック(たとえば、テンプレートファイルの一貫した命名規則)を使用すると、tmplマップを自動的に生成することさえ可能です。

121
tux21b

基本テンプレートを実行する場合、値を子テンプレートに渡す必要があります。ここでは単に「。」を渡すため、すべてが渡されます。

テンプレート1は{{。}}を表示します

{{define "base"}}
<html>
        <div class="container">
            {{.}}
            {{template "content" .}}
        </div>
    </body>
</html>
{{end}}

テンプレート2は、親に渡された{{.domains}}を表示します。

{{define "content"}}
{{.domains}}
{{end}}

{{template "content"。}}ではなく{{template "content"。}}を使用した場合、.domainsはコンテンツテンプレートからアクセスできないことに注意してください。

DomainsData := make(map[string]interface{})
    DomainsData["domains"] = domains.Domains
    if err := groupsTemplate.ExecuteTemplate(w, "base", DomainsData); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
9
robert king

Pongo を使用します。これは、Djangoと同様に、テンプレート継承のために{{extends}}および{{block}}タグをサポートするGoテンプレートのスーパーセットです。

5
Rob

私は何日もこの答えに戻ってきて、最後に弾丸を噛み、これのために小さな抽象化層/プリプロセッサを書きました。基本的に:

  • 「extends」キーワードをテンプレートに追加します。
  • 'define'呼び出しのオーバーライドを許可します(したがって、greggoryのデフォルト値が可能です)
  • 定義されていない「テンプレート」呼び出しを許可します。空の文字列を与えるだけです
  • のデフォルト値を設定します。の「テンプレート」呼び出し親の

https://github.com/daemonl/go_sweetpl

4
daemonl

他のテンプレートパッケージで働いていたので、今ではほとんどが標準のhtml/templateパッケージで働いていますが、それが提供するシンプルさやその他の利点に感謝しないのは素朴だったと思います。私は受け入れられた答えに非常に似たアプローチを使用し、次の変更を加えます

追加のbaseテンプレートでレイアウトをラップする必要はありません。解析されたファイルごとにテンプレートブロックが作成されるため、この場合は冗長です。goの新しいバージョンで提供されるブロックアクションも使用したいです。 、子テンプレートで提供しない場合にデフォルトのブロックコンテンツを使用できます

// base.html
<head>{{block "head" .}} Default Title {{end}}</head>
<body>{{block "body" .}} default body {{end}}</body>

ページテンプレートは次と同じにすることができます

// Content of index.html:
{{define "head"}}<title>index</title>{{end}}
{{define "body"}}index{{end}}

// Content of other.html:
{{define "head"}}<title>other</title>{{end}}
{{define "body"}}other{{end}}

テンプレートを実行するには、次のように呼び出す必要があります

tmpl["index.html"].ExecuteTemplate(os.Stdout, "base.html", data)
1
allyraza