Golang Multi模板缓存

时间:2017-08-22 22:52:14

标签: go

我是Golang的新手,我正在尝试使用模板文件和良好的缓存系统来设置一个Web项目。

我有layout.html1.html2.html

所以我在渲染函数中加载layout.html

err := templates.ExecuteTemplate(w, "layout.html", nil)

layout.html看起来像这样:

...   
<body>{{template "content" .}}</body>
...

1.html

{{define "content"}}This is the first page.{{end}}

2.html

{{define "content"}}This is the second page.{{end}}

我无法使用

var templates = template.Must(template.ParseFiles(
    "layout.html",
    "1.html",
    "2.html"))

由于2.html覆盖1.html

所以我有两种方式:

  1. 在每个处理函数中定义ParseFiles。 (每次呈现页面时)非常糟糕的性能
  2. 在init函数(example)中定义这样的模板数组: templates["1"] = template.Must(template.ParseFiles("layout.html","1.html")) templates["2"] = template.Must(template.ParseFiles("layout.html","2.html"))
  3. 有没有新方法或更好的方法来做到这一点?

2 个答案:

答案 0 :(得分:2)

在我的项目中,我使用了这个辅助函数:

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

tmpls是包含所有已解析模板作为“子模板”的模板,例如来自ParseFileslayout.html看起来像这样:

<main class="container">
{{template "content" .}}
</main>

虽然其他模板是这样的:

<h1>Welcome</h1>

请注意,内容模板不需要以{{define "content"}}开头。

答案 1 :(得分:1)

包级映射或变量都是缓存已编译模板的好方法。上面#2中的代码没问题。以下是如何使用包级变量:

var t1 = template.Must(template.ParseFiles("layout.html","1.html"))
var t2 = template.Must(template.ParseFiles("layout.html","2.html"))

使用这样的变量:

err := t1.Execute(w, data)

问题中的代码和此代码中的此代码加载&#34; layout.html&#34;两次。这可以避免:

var layout = template.Must(template.ParseFiles("layout.html"))
var t1 = template.Must(layout.Clone().ParseFiles("1.html"))
var t2 = template.Must(layout.Clone().ParseFiles("2.html"))