Is it possible to have nested templates in Go using the standard library? (Google App Engine)

How to get nested templates like Jinja in python runtime. TBC, which I mean, as I have a bunch of templates inherited from basic templates, just filling in the blocks of basic templates such as Jinja / django-templates. Is it possible to use only html/template in the standard library.

If this is not possible, what are my alternatives. The mustache seems to be an option, but then I will overlook those nice subtle html/template functions like context-sensitive escaping, etc.? What are the other alternatives?

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

Thanks for reading.

+69
google-app-engine go template-engine mustache
Jul 13 '12 at 9:28
source share
4 answers

Yes it is possible. A html.Template is actually a collection of template files. If you execute a specific block in this set, it has access to all other blocks defined in this set.

If you create a map of such template sets on your own, you have the same flexibility that Jinja / Django offers. The only difference is that the html / template package does not have direct access to the file system, so you will have to analyze and compile the templates yourself.

Consider the following example with two different pages ("index.html" and "other.html") that inherit from "base.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}} 

And the following template sets map:

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

Now you can display the "index.html" page by calling

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

and you can display the page "other.html" by calling

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

With some tricks (for example, a consistent naming convention for your template files), it is even possible to create a tmpl map automatically.

+111
Jul 13 2018-12-12T00:
source share

Please note that when executing the basic template, you must pass values ​​to child templates, here I just pass "." So that everything is transferred.

template displays {{.}}

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

pattern two displays {{.domains}}, which is passed to the parent.

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

Please note that if we used {{template "content".}} Instead of {{template "content".}}, Then the domain domain will not be accessible from the content template.

 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) } 
+6
Jun 30 '16 at 1:57
source share

Use Pongo , which is a super-set of Go templates that support the {{extends}} and {{block}} tags to inherit templates like Django.

+5
Apr 02 '13 at 13:28
source share

I come back to this answer for several days, finally launched a bullet and wrote a small layer of abstraction / preprocessor for this. This is basically:

  • Adds the keyword 'extends' to templates.
  • Allows overriding the 'define' calls (therefore default values ​​for greggory are possible)
  • Allows undefined "template" calls, they just give an empty string
  • Sets the default value. in "template" calls. parent

https://github.com/daemonl/go_sweetpl

+4
Feb 03 '14 at 7:13
source share



All Articles