package main
import (
"bytes"
"html/template"
"os"
)
func main() {
var err error
// our main template here calls a sub template
tpl := template.New("main")
// provide a func in the FuncMap which can access tpl to be able to look up templates
tpl.Funcs(map[string]interface{}{
"CallTemplate": func(name string, data interface{}) (ret template.HTML, err error) {
buf := bytes.NewBuffer([]byte{})
err = tpl.ExecuteTemplate(buf, name, data)
ret = template.HTML(buf.String())
return
},
})
// this is the main template
_, err = tpl.Parse(`
{{$Name := "examplesubtpl"}}
from main template
{{CallTemplate $Name .}}
`)
if err != nil {
panic(err)
}
// whatever code to dynamically figure out what templates to load
// a stub just to demonstrate
_, err = tpl.New("examplesubtpl").Parse(`
this is from examplesubtpl - see, it worked!
`)
if err != nil {
panic(err)
}
err = tpl.Execute(os.Stdout, map[string]interface{}{})
if err != nil {
panic(err)
}
}
6条答案
按热度按时间xnifntxz1#
作为对这一点的说明和后续行动,我最终结束了这个问题的两个主要答案:1)尽量避免这种情况。在某些情况下,简单的if语句就能很好地工作。2)我可以使用FuncMap中的一个函数来实现这一点,这个函数只进行单独的渲染。这不是世界上最好的事情,但它确实有效并解决了问题。下面是一个完整的独立演示,展示了这个想法:
3htmauhk2#
另一种方法,虽然可能不是一个更好的方法,将有单独的模板文件,所有提供相同命名的模板。例如,假设你有一个网页的共享布局:
在每个页面中执行以下操作:
然后在代码中合并它们:
k4emjkb13#
一个与我共事的天才开发人员想出了一个不同的方法,那就是对Template示例进行后处理,以找到任何未定义的模板包含,并在文件系统中查找匹配的文件,然后解析找到的每个文件;然后再渲染。
这将为您提供如下设置:
浏览次数/index.html:
包含/页面 Package .html:
ServeHTTP()
方法在“views”目录中查找文件,加载并解析它,然后调用TmplIncludeAll()
(如下所示)。最后,我将这个基本概念改编为几个函数,如下所示:
t
是解析后但渲染前的模板,fs
是“views”和“includes”所在的目录(参见上文)。这是我最喜欢的方法,我已经用了一段时间了。它的优点是只有一个模板渲染,错误消息很好很干净,Go语言的模板标记可读性很强。如果html/template.Template能让它更容易实现,那就太好了,但总体来说,它是一个很好的解决方案。
ghhkc1vu4#
使用**htmltemplate.HTML()**将解析后的模板(“email/test”)插入到另一个模板(“email/main”)中
在“电子邮件/主页”上
jfewjypa5#
面对同样的问题,而使用杜松子酒,最简单的解决方案是:
基本上我把html内容分割成单独的文件,然后单独调用它们。只要响应代码相同(例如:200),则不会触发任何问题。
hmtdttj46#
如果模板变量针对一组已知的备选项进行选择,那么我最终会手动或自动生成一个后缀来在模板之间进行选择。
我在其他地方使用的另一种方法是,在执行模板之前,解析一个动态生成的小模板,如下所示: