是否可以使用标准库在Go中嵌套模板? (Google App Engine)

时间:2012-07-13 09:28:28

标签: google-app-engine go template-engine mustache

如何在python运行时获得像Jin​​ja这样的嵌套模板。 TBC我的意思是如何从基本模板继承一堆模板,只需在基本模板的块中归档,就像Jinja / django-templates一样。是否可以在标准库中使用html/template

如果不可能,我的替代方案是什么。小胡子似乎是一个选项,但我会错过html/template那些漂亮的微妙特征,如上下文敏感的转义等?还有什么其他选择?

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

感谢阅读。

5 个答案:

答案 0 :(得分:120)

是的,这是可能的。 html.Template实际上是一组模板文件。如果在此集合中执行已定义的块,则它可以访问此集合中定义的所有其他块。

如果您自己创建此类模板集的地图,则您具有Jinja / Django提供的基本相同的灵活性。唯一的区别是html/template包无法直接访问文件系统,因此您必须自己解析和撰写模板。

考虑以下示例,其中两个页面(“index.html”和“other.html”)都继承自“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}}

以下模板集地图:

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

您现在可以通过调用

呈现“index.html”页面
tmpl["index.html"].Execute("base", data)

您可以通过调用

来呈现“other.html”页面
tmpl["other.html"].Execute("base", data)

通过一些技巧(例如模板文件的一致命名约定),甚至可以自动生成tmpl地图。

答案 1 :(得分:9)

请注意,当您执行基本模板时,必须将值传递给子模板,在这里我只需传递“。”,以便传递所有内容。

模板一显示{{。}}

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

模板二显示传递给父级的{{.domains}}。

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

注意,如果我们使用{{template“content”。}}而不是{{template“content”。}},则无法从内容模板访问.domains。

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

答案 2 :(得分:5)

使用Pongo,这是一套超级Go模板,支持{{extends}}和{{block}}标签进行模板继承,就像Django一样。

答案 3 :(得分:4)

我已经回到这个问题好几天了,最后咬了一口子,为此写了一个小的抽象层/预处理器。它基本上是:

  • 将“extends”关键字添加到模板中。
  • 允许覆盖'define'调用(因此可以使用gregory的默认值)
  • 允许未定义的“模板”调用,它们只是提供一个空字符串
  • 设置默认值。在'模板'调用。父母的

https://github.com/daemonl/go_sweetpl

答案 4 :(得分:0)

曾经与其他模板程序包一起工作过,现在有一天我主要使用标准的html / template程序包,我想我很天真地不欣赏它提供的简单性和其他优点。我使用非常相似的方法对接受的答案进行了以下更改

您不需要使用其他base模板来包装布局,为每个已解析的文件创建一个模板块,因此在这种情况下它是多余的,我也想使用新版本中提供的block操作of go,如果您未在子模板中提供模板,则可以使用默认的阻止内容

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

您的页面模板可以与

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

现在要执行模板,您需要像这样

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