1. ホーム
  2. google-app-engine

[解決済み] 標準ライブラリを使って、Goでネストしたテンプレートを持つことは可能ですか?

2023-02-26 11:05:20

質問

Jinjaがpythonランタイムで持っているようなネストされたテンプレートを得るにはどうしたらよいでしょうか。私が言いたいのは、Jinja/django-templates がそうであるように、たくさんのテンプレートがベーステンプレートを継承し、ベーステンプレートのブロックにファイリングする方法を教えてください、ということです。それは、単に html/template を標準ライブラリで使用することは可能でしょうか?

それが可能でない場合、私の代替は何でしょう。Mustache は選択肢の 1 つに見えますが、その場合、 の素晴らしい微妙な機能を逃してしまうことになります。 html/template の微妙な機能、例えば文脈依存のエスケープなどを見逃してしまうのでしょうか?他の選択肢は何ですか?

(環境: Google App Engin, Go runtime v1, Dev - Mac OSx lion)

お読みいただきありがとうございます。

どのように解決するのですか?

はい、可能です。A 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 マップを自動的に生成することも可能です。