html/template
Goを使用してテンプレートを埋め込むことに頭を悩ませようとしています。私はロジックのないテンプレートのデザインがとても好きで、期待通りに安全にエスケープする能力に自信を持っています (他のテンプレート ライブラリがこれを間違えることがあります)。
ただし、「最終的な」テンプレート名に基づいて HTTP ハンドラーでテンプレートをレンダリングするための小さなヘルパーを実装しようとすると、少し問題が発生します。私の base.tmpl は、すべてのページで事実上「標準」であり、そうでない場合は{{ template checkoutJS }}
、base.tmpl に設定し、設定することでページごとの JS を追加できます{{ define checkoutJS }}https://path.to/extra.js {{ end }}
。
renderTemplate(w, "template_name.tmpl", data)
HTTP ハンドラーで、data
入力したいものを含む文字列または構造体を含む map[string]interface{} はどこにあると言えるようにしたいと考えています。
これまでのコードは次のとおりです。
base.tmpl
{{ define "base" }}
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ template "title" . }}</title>
</head>
<body>
<div id="sidebar">
...
</div>
{{ template "content" }}
<div id="footer">
...
</div>
</body>
</html>
create_listing.tmpl
{{ define "title" }}Create a New Listing{{ end }}
{{ define "content" }}
<form>
...
</form>
{{ end }}
login_form.tmpl
{{ define "title" }}Login{{ end }}
{{ define "content" }}
<form>
...
</form>
{{ end }}
main.go
package main
import (
"fmt"
"github.com/gorilla/mux"
"html/template"
"log"
"net/http"
)
// Template handling shortcuts
var t = template.New("base")
func renderTemplate(w http.ResponseWriter, tmpl string, data map[string]interface{}) {
err := t.ExecuteTemplate(w, tmpl, data)
// Things will be more elegant than this: just a placeholder for now!
if err != nil {
http.Error(w, "error 500:"+" "+err.Error(), http.StatusInternalServerError)
}
}
func monitorLoginForm(w http.ResponseWriter, r *http.Request) {
// Capture forms, etc.
renderTemplate(w, "login_form.tmpl", nil)
}
func createListingForm(w http.ResponseWriter, r *http.Request) {
// Grab session, re-populate form if need be, generate CSRF token, etc
renderTemplate(w, "create_listing.tmpl", nil)
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/monitor/login", monitorLoginForm)
http.Handle("/", r)
log.Fatal(http.ListenAndServe(":8000", nil))
}
func init() {
fmt.Println("Starting up.")
_, err := t.ParseGlob("templates/*.tmpl")
if err != nil {
log.Fatal("Error loading templates:" + err.Error())
}
}
これはコンパイルされますが、ハンドラーから空の応答が返されます。2 番目のハンドラーのルートがないことに注意してください。このコードはrenderTemplate()
、ハンドラーからどのように呼び出したいかを示すためのものです。