Standart kitaplığı kullanarak Go'da iç içe şablonlara sahip olmak mümkün müdür?


88

Jinja'nın python çalışma zamanında olduğu gibi iç içe geçmiş şablonları nasıl edinebilirim? TBC demek istediğim, Jinja / django-şablonlarının yaptığı gibi, bir temel şablondan miras alınan bir grup şablona nasıl sahip olduğumdur. Sadece html/templatestandart kitaplıkta kullanmak mümkün mü ?

Bu bir olasılık değilse, alternatiflerim nelerdir? Bıyık bir seçenek gibi görünüyor, ancak o zaman html/templateiçeriğe duyarlı kaçış gibi hoş ince özellikleri kaçırır mıyım? Başka hangi alternatifler var?

(Çevre: Google App Engin, Go runtime v1, Dev - Mac OSx lion)

Okuduğunuz için teşekkürler.

Yanıtlar:


133

Evet mümkün. A html.Templateaslında bir dizi şablon dosyasıdır. Bu sette tanımlı bir blok yürütürseniz, bu sette tanımlanan diğer tüm bloklara erişebilir.

Bu tür şablon kümelerinin haritasını kendi başınıza oluşturursanız, Jinja / Django'nun sunduğu esnekliğin aynısına sahip olursunuz. Tek fark, html / şablon paketinin dosya sistemine doğrudan erişimi olmamasıdır, bu nedenle şablonları kendi başınıza ayrıştırıp oluşturmanız gerekir.

Her ikisi de "base.html" den devralan iki farklı sayfadan ("index.html" ve "other.html") oluşan aşağıdaki örneği düşünün:

// 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}}

Ve aşağıdaki şablon kümeleri haritası:

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"))

Artık "index.html" sayfanızı arayarak oluşturabilirsiniz

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

ve "other.html" sayfanızı şu numarayı arayarak oluşturabilirsiniz:

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

Bazı hilelerle (örneğin, şablon dosyalarınızın tutarlı bir adlandırma kuralı), tmplharitayı otomatik olarak oluşturmak bile mümkündür .


3
Örneğin, "head" için varsayılan verilere sahip olmak mümkün mü?
gregghz

18
Aramam gereken gerçek şablonları işlemek için buraya ekleyeceğim tmpl["index.html"].ExecuteTemplate(w, "base", data).
hermansc

base.html iki kez ayrıştırılır ve saklanır. Golang.org/pkg/text/template/#example_Template_share
Maarten

3
Verileri yuvalanmış bir şablona aktarırken sorun yaşıyorum. İle ilgili veriler {{ .SomeData }}iç şablonda görüntülenmez. Dış işler.
0xAffe

eğer bu konularda template.ParseFiles("index.html", "base.html")olduğunu template.ParseFiles("base.html", "index.html")?
shackra

10

not, temel şablonunuzu çalıştırdığınızda, değerleri alt şablonlara aktarmanız gerekir, burada her şeyin aktarılması için basitçe "." iletiyorum.

şablon bir görüntülenir {{.}}

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

şablon iki, üst öğeye aktarılan {{.domains}} öğesini görüntüler.

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

{{Template "content".}} Yerine {{template "content".}} Kullansaydık, .domainlere içerik şablonundan erişilemezdi.

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)
    }

5
Modeli aktarmak, takıldığım bir detay. ;) Teşekkürler
Patrick

1
ben de - anlamak için biraz zaman aldı :)
robert king

1
Ne! {{Template}} yer tutucusunun sonundaki küçük küçük noktanın bu kadar anlamlı olduğuna inanamıyorum! Neden öğreticilerde veya resmi Go belgelerinde herhangi bir yerde bahsedilmiyor? Şaşırdım ama cevabını bulduğum için çok mutluyum! Çok teşekkür ederim, şimdi çeşitli seviyelerde yerleştirme içeren şablonlarım çok güzel çalışıyor!
Gwyneth Llewelyn

Tam olarak, anlamaya çalıştığım şeyin aynısı!
devforfu

5

diğer şablon paketleriyle çalıştığım için, şimdi çoğunlukla standart html / şablon paketiyle çalıştığım bir gün, sağladığı basitliği ve diğer güzellikleri takdir edemediğimi tahmin ediyorum. Aşağıdaki değişikliklerle kabul edilen yanıta çok benzer bir yaklaşım kullanıyorum

mizanpajlarınızı ek baseşablonla sarmanıza gerek yoktur , her ayrıştırılmış dosya için bir şablon bloğu oluşturulur, bu durumda gereksizdir, ayrıca go'nun yeni sürümünde sağlanan blok eylemini kullanmayı tercih ederim, Alt şablonlarda bir tane sağlamamanız durumunda varsayılan engelleme içeriği

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

ve siz sayfa şablonları aynı olabilir

// 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}}

şimdi bu şekilde adlandırmanız gereken şablonları yürütmek için

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

4

Kullanım Pongo sadece Django gibi, şablon miras {{uzanır}} ve {{blok}} etiketlerini destekler Git şablonları bir süper dizi.


4

Bu cevaba günlerdir geri dönüyorum, sonunda mermiyi ısırdım ve bunun için küçük bir soyutlama katmanı / ön işlemci yazdım. Temelde:

  • Şablonlara 'extends' anahtar kelimesini ekler.
  • Çağrıları geçersiz kılmaya izin verir (bu nedenle greggory için varsayılan değerler mümkündür)
  • Tanımlanmamış 'şablon' çağrılarına izin verir, sadece boş bir dize verirler
  • Varsayılan değerini ayarlar. 'şablon' içindeki çağrıları. ebeveynin

https://github.com/daemonl/go_sweetpl

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.