【问题标题】:Golang Multi templates cachingGolang 多模板缓存
【发布时间】:2017-08-22 22:52:13
【问题描述】:

我是 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"))

有什么新方法或更好的方法吗?

【问题讨论】:

  • 已解析的模板不会相互“覆盖”,除非它们具有完全相同的文件名(但路径不同)。它们都单独存储,您只需使用文件名执行即可。
  • @RayfenWindspear,你能给我举个例子吗

标签: go


【解决方案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)

问题中的代码和此答案中的上述代码会加载“layout.html”两次。这是可以避免的:

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

【讨论】:

  • Thk,没关系,但我不想为每个新页面定义一个新变量或数组索引。没有其他方法可以动态渲染?
【解决方案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"}}开头。

【讨论】:

    猜你喜欢
    • 2014-07-17
    • 1970-01-01
    • 2010-09-19
    • 2015-04-23
    • 1970-01-01
    • 2019-02-07
    • 2022-01-24
    • 2017-10-25
    • 1970-01-01
    相关资源
    最近更新 更多