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

sri*_*sri 82 google-app-engine template-engine go mustache

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

如果这不可能,我的替代方案是什么.小胡子似乎是一个选项,但我会错过那些html/template像上下文敏感的逃避等的微妙的功能?还有什么其他选择?

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

谢谢阅读.

tux*_*21b 122

对的,这是可能的.A 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}}
Run Code Online (Sandbox Code Playgroud)

以下是模板集的地图:

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"))
Run Code Online (Sandbox Code Playgroud)

您现在可以通过调用来呈现"index.html"页面

tmpl["index.html"].Execute("base", data)
Run Code Online (Sandbox Code Playgroud)

并且您可以通过调用来呈现"other.html"页面

tmpl["other.html"].Execute("base", data)
Run Code Online (Sandbox Code Playgroud)

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

  • 我只是在这里添加,为了呈现实际模板,我必须调用`tmpl ["index.html"].ExecuteTemplate(w,"base",data)`. (18认同)
  • 是否可以拥有默认数据,例如"head"? (3认同)
  • 将数据传递给嵌套模板时遇到问题.来自`{{.SomeData}}`的数据不会显示在内部模板中.外部工程. (3认同)
  • @0xAffe 使用 ` . ` 在 `{{ 模板“temp” 中。}}` 使数据可用于嵌套模板 (3认同)

rob*_*ing 9

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

模板一显示{{.}}

{{define "base"}}
<html>
        <div class="container">
            {{.}}
            {{template "content" .}}
        </div>
    </body>
</html>
{{end}}
Run Code Online (Sandbox Code Playgroud)

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

{{define "content"}}
{{.domains}}
{{end}}
Run Code Online (Sandbox Code Playgroud)

请注意,如果我们使用{{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)
    }
Run Code Online (Sandbox Code Playgroud)

  • 传递模型是我坚持的细节.;) 谢谢 (4认同)

小智 6

使用过其他模板包,现在我主要使用标准的 html/模板包,我想我很天真,不喜欢它提供的简单性和其他好处。我使用非常相似的方法来接受以下更改

你不需要用额外的base模板包装你的布局,为每个解析的文件创建一个模板块,所以在这种情况下它是多余的,我也喜欢使用新版本的 go 中提供的块操作,它允许你有默认块内容,以防您在子模板中不提供

// base.html
<head>{{block "head" .}} Default Title {{end}}</head>
<body>{{block "body" .}} default body {{end}}</body>
Run Code Online (Sandbox Code Playgroud)

并且您的页面模板可以与

// 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}}
Run Code Online (Sandbox Code Playgroud)

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

tmpl["index.html"].ExecuteTemplate(os.Stdout, "base.html", data)
Run Code Online (Sandbox Code Playgroud)


Rob*_*Rob 5

使用Pongo,它是一组超级模板,支持模板继承的{{extends}}和{{block}}标签,就像Django一样.


dae*_*onl 5

我已经回到这个答案好几天了,终于硬着头皮为此写了一个小的抽象层/预处理器。它基本上:

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

https://github.com/daemonl/go_sweetpl