用于Web应用程序的Golang模板

时间:2016-11-10 12:11:15

标签: go go-templates

我正在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中使用模板和'布局'的策略吗?

2 个答案:

答案 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助手,它就不能成为一个变量,它被锁定为只使用静态字符串。