Oui c'est possible. A html.Template
est en fait un ensemble de fichiers modèles. Si vous exécutez un bloc défini dans cet ensemble, il a accès à tous les autres blocs définis dans cet ensemble.
Si vous créez vous-même une carte de ces ensembles de modèles, vous avez fondamentalement la même flexibilité qu'offre Jinja / Django. La seule différence est que le package html / template n'a pas d'accès direct au système de fichiers, vous devez donc analyser et composer les modèles vous-même.
Prenons l'exemple suivant avec deux pages différentes ("index.html" et "other.html") qui héritent toutes deux de "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}}
Et la carte suivante des ensembles de modèles:
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"))
Vous pouvez maintenant afficher votre page "index.html" en appelant
tmpl["index.html"].Execute("base", data)
et vous pouvez afficher votre page "other.html" en appelant
tmpl["other.html"].Execute("base", data)
Avec quelques astuces (par exemple une convention de dénomination cohérente de vos fichiers modèles), il est même possible de générer la tmpl
carte automatiquement.
tmpl["index.html"].ExecuteTemplate(w, "base", data)
.{{ .SomeData }}
ne seront pas affichées dans le modèle interne. Les œuvres extérieures.template.ParseFiles("index.html", "base.html")
c'esttemplate.ParseFiles("base.html", "index.html")
?notez que lorsque vous exécutez votre modèle de base, vous devez transmettre des valeurs aux modèles enfants, ici je passe simplement ".", pour que tout soit transmis.
le modèle un affiche {{.}}
{{define "base"}} <html> <div class="container"> {{.}} {{template "content" .}} </div> </body> </html> {{end}}
le modèle deux affiche {{.domains}} qui est passé au parent.
{{define "content"}} {{.domains}} {{end}}
Notez que si nous utilisions {{template "content".}} Au lieu de {{template "content".}}, .Domains ne serait pas accessible à partir du modèle de contenu.
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) }
la source
ayant travaillé avec d'autres packages de modèles, maintenant je travaille principalement avec des packages html / template standard, je suppose que j'étais naïf de ne pas apprécier la simplicité qu'il offre et d'autres goodies. J'utilise une approche très similaire à la réponse acceptée avec les modifications suivantes
vous n'avez pas besoin d'encapsuler vos mises en page avec un
base
modèle supplémentaire , un bloc de modèle est créé pour chaque fichier analysé donc dans ce cas, il est redondant, j'aime aussi utiliser l'action de blocage fournie dans la nouvelle version de go, qui vous permet d'avoir contenu de bloc par défaut au cas où vous n'en fournissez pas un dans les modèles enfants// base.html <head>{{block "head" .}} Default Title {{end}}</head> <body>{{block "body" .}} default body {{end}}</body>
et vos modèles de page peuvent être les mêmes que
// 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}}
maintenant pour exécuter les modèles, vous devez l'appeler comme ça
tmpl["index.html"].ExecuteTemplate(os.Stdout, "base.html", data)
la source
Utilisez Pongo , qui est un super-ensemble de modèles Go prenant en charge les balises {{extend}} et {{block}} pour l'héritage de modèles, tout comme Django.
la source
Je reviens sur cette réponse depuis des jours, j'ai finalement mordu la balle et j'ai écrit une petite couche d'abstraction / pré-processeur pour cela. Il s'agit essentiellement:
https://github.com/daemonl/go_sweetpl
la source