我正在GoLang中编写一个Web应用程序,而不是使用任何框架。
我正在尝试创建一个与nodejs中的布局类似的layout
。
=== layout.html ====
{{ define "layout"}}
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<link href="/static/style.css" rel="stylesheet" media="all" type="text/css">
</head>
<body>
{{ template "content"}}
</body>
</html>
{{ end }}
然后我在home.html中提供了一些内容
{{ define "content"}}
<h1>{{.Title}}</h1>
<div>This is a test</div>
{{ end }}
这种方法有两个问题
(1)我的执行模板代码,似乎没有将数据传递给内容
templates.ExecuteTemplate(w, "layout", &Page{Title: "Home", Body: nil})
(2)如果我想让多个页面具有相同的布局,则上述操作无效,因为它没有指定要加载的内容。
有人可以解释一下在GoLang中使用模板和'布局'的策略吗?
答案 0 :(得分:1)
(1)我的执行模板代码,似乎没有将数据传递给内容
正如人们在评论中指出的那样,您需要使用数据显式调用模板:
{{ template "content" . }}
注意"content"
部分之后的点。
(2)如果我想让多个页面具有相同的布局,则上述操作无效,因为它没有指定要加载的内容。
有几种方法可以解决这个问题。我做的是这个。我在每个模板中都没有{{ define "content" }}
。相反,我将所有模板解析为一个:
tmpls, err := template.ParseGlob(tmplGlob)
然后对于每个请求,我克隆布局并将所需模板设置为"content"
:
func executeTemplate(tmpls *template.Template, tmplName string, w io.Writer, data interface{}) error {
var err error
layout := tmpls.Lookup("layout.html")
if layout == nil {
return errNoLayout
}
layout, err = layout.Clone()
if err != nil {
return err
}
t := tmpls.Lookup(tmplName)
if t == nil {
return errNoTemplate
}
_, err = layout.AddParseTree("content", t.Tree)
if err != nil {
return err
}
return layout.Execute(w, data)
}
答案 1 :(得分:0)
(2)如果我想让多个页面具有相同的布局,则上述操作无效,因为它没有指定要加载的内容。
你需要为此事建立一些东西。
它可以是template func,它知道模板,接收块名称和调用t.executeTemplate的args,就像你做的那样。
但是这种方法有一个严重的缺点,因为它要求每个请求都产生自己的编译模板。
它可以是视图的方法。这可以让你构建一次模板,对每个请求重复使用这个实例,只有参数会改变。
无论如何,如果你继续使用内置的template
助手,它就不能成为一个变量,它被锁定为只使用静态字符串。