Ya itu mungkin. A html.Template
sebenarnya adalah sekumpulan file template. Jika Anda menjalankan blok yang ditentukan dalam himpunan ini, ia memiliki akses ke semua blok lain yang ditentukan dalam himpunan ini.
Jika Anda membuat peta set templat seperti itu sendiri, pada dasarnya Anda memiliki fleksibilitas yang sama dengan yang ditawarkan Jinja / Django. Perbedaan satu-satunya adalah paket html / template tidak memiliki akses langsung ke sistem file, jadi Anda harus mengurai dan membuat template sendiri.
Pertimbangkan contoh berikut dengan dua halaman berbeda ("index.html" dan "other.html") yang keduanya diwarisi dari "base.html":
{{define "base"}}<html>
<head>{{template "head" .}}</head>
<body>{{template "body" .}}</body>
</html>{{end}}
{{define "head"}}<title>index</title>{{end}}
{{define "body"}}index{{end}}
{{define "head"}}<title>other</title>{{end}}
{{define "body"}}other{{end}}
Dan peta set template berikut:
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"))
Sekarang Anda dapat merender halaman "index.html" dengan memanggil
tmpl["index.html"].Execute("base", data)
dan Anda dapat merender halaman "other.html" dengan memanggil
tmpl["other.html"].Execute("base", data)
Dengan beberapa trik (misalnya, konvensi penamaan yang konsisten dari file template Anda), tmpl
peta dapat dibuat secara otomatis.
tmpl["index.html"].ExecuteTemplate(w, "base", data)
.{{ .SomeData }}
tidak akan ditampilkan di templat bagian dalam. Pekerjaan luar.template.ParseFiles("index.html", "base.html")
initemplate.ParseFiles("base.html", "index.html")
?Catatan, saat Anda menjalankan template dasar, Anda harus meneruskan nilai ke template anak, di sini saya hanya meneruskan ".", sehingga semuanya diturunkan.
template satu menampilkan {{.}}
{{define "base"}} <html> <div class="container"> {{.}} {{template "content" .}} </div> </body> </html> {{end}}
template dua menampilkan {{.domains}} yang diteruskan ke induknya.
{{define "content"}} {{.domains}} {{end}}
Perhatikan, jika kami menggunakan {{template "content".}} Dan bukan {{template "content".}}, .Domains tidak akan bisa diakses dari template konten.
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) }
sumber
setelah bekerja dengan paket template lain, sekarang hari saya kebanyakan bekerja dengan paket html / template standar, saya rasa saya naif untuk tidak menghargai kesederhanaan yang diberikannya dan barang lainnya. Saya menggunakan pendekatan yang sangat mirip untuk menerima jawaban dengan perubahan berikut
Anda tidak perlu membungkus tata letak Anda dengan
base
templat tambahan , blok templat dibuat untuk setiap file yang diurai jadi dalam hal ini berlebihan, saya juga suka menggunakan tindakan blokir yang disediakan dalam versi baru go, yang memungkinkan Anda untuk memilikinya konten blokir default jika Anda tidak menyediakannya di template anak// base.html <head>{{block "head" .}} Default Title {{end}}</head> <body>{{block "body" .}} default body {{end}}</body>
dan templat halaman Anda bisa sama dengan
// 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}}
sekarang untuk menjalankan templat Anda perlu memanggilnya seperti itu
tmpl["index.html"].ExecuteTemplate(os.Stdout, "base.html", data)
sumber
Gunakan Pongo , yang merupakan himpunan super dari Template Go yang mendukung tag {{extends}} dan {{block}} untuk pewarisan template, seperti Django.
sumber
Saya telah kembali ke jawaban ini selama berhari-hari, akhirnya menggigit peluru dan menulis lapisan abstraksi kecil / prosesor pra untuk ini. Ini pada dasarnya:
https://github.com/daemonl/go_sweetpl
sumber