2017-08-22 59 views
1

我是新来的Golang的世界,我试图建立一个模板文件和良好的缓存系统的Web项目。Golang多模板缓存

我有layout.html1.html,2.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。 (每次呈现页面时)非常糟糕PERF
  2. 定义模板的数组像这样在初始化函数(example): templates["1"] = template.Must(template.ParseFiles("layout.html","1.html")) templates["2"] = template.Must(template.ParseFiles("layout.html","2.html"))

有没有什么新的方式或更好的方式来做到这一点?

+1

解析的模板不“越权”对方,除非他们有相同的确切的文件名(但不同的路径)。它们都是分开存储的,你只需要使用文件名来执行它。 – RayfenWindspear

+0

@RayfenWindspear,你能告诉我一个例子PLS –

回答

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

THK,它的好,但我并不想要定义的数组的新变量或指数为每个新的一页。没有其他方式来动态渲染? –

1

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

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