GO:如何在golang中渲染多个模板?

fmt*_*int 27 google-app-engine go

创建一个基本模板.用它渲染first.html一个模板.

eg. :
    var tmpl = template.Must(template.ParseFiles(
    "templates/base.html",
    "templates/first.html",
    ))
Run Code Online (Sandbox Code Playgroud)

但我也想添加更多的.html文件进行渲染.任何参考?

iob*_*boi 80

如果在模板文件夹中定义所有模板,则可以使用以下方法轻松解析整个目录:

template.Must(template.ParseGlob("YOURDIRECTORY/*"))
Run Code Online (Sandbox Code Playgroud)

例如:

head.html

{{define "header"}}
     <head>
         <title>Index</title>
     </head>
{{end}}
Run Code Online (Sandbox Code Playgroud)

的index.html

{{define "indexPage"}}
    <html>
    {{template "header"}}
    <body>
        <h1>Index</h1>
    </body>
    </html>
{{end}}
Run Code Online (Sandbox Code Playgroud)

main.go

package main

import(
    "html/template"
)

// compile all templates and cache them
var templates = template.Must(template.ParseGlob("YOURTEMPLATEDIR/*"))

func main(){
    ...
}

func IndexHandler(w http.ResponseWriter, r *http.Request) {

    // you access the cached templates with the defined name, not the filename
    err := templates.ExecuteTemplate(w, "indexPage", nil)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
}
Run Code Online (Sandbox Code Playgroud)

使用执行indexPage-Template templates.ExecuteTemplate(w, "indexPage", nil)

  • 这应该是公认的答案.这个答案比文档更清楚.它显示了如何使用全局`templates`变量,因此您可以在服务器启动时加载所有模板,而不是在实际的处理程序中加载(将在每个页面加载时加载).它还显示了如何通过名称定义模板,然后使用`templates.ExecuteTemplate`调用它,这非常有用.到目前为止,我在这个主题上看到的最好的文档...... (2认同)

ANi*_*sus 7

您只需将它们添加为参数即可轻松添加更多.html文件:

var tmpl = template.Must(template.ParseFiles(
    "templates/base.html",
    "templates/first.html",
    "templates/second.html",
))
Run Code Online (Sandbox Code Playgroud)

只要第一个和第二个不定义相同的模板,这样就可以正常工作.
但是,模板包不允许使用模板名称的管道值动态调用模板.所以,如果你试图做一些类似于我下面的例子,那么它将无法工作.

存在一些变通方法,并且在Go-nuts上有一个关于它的讨论.但似乎模板包的设计是*Template每页应该有一个对象.

尝试动态模板调用的示例有缺陷:
错误:模板调用中出现意外的".Content"

package main

import (
    "log"
    "os"
    "text/template"
)

const base= `<!DOCTYPE html>
<html>
    <head><title>Title</title></head>
<body>
    {{template .Content}}
</body>
</html>`

const first = `{{define "first"}}This is the first page{{end}}`
const second = `{{define "second"}}And here is the second{{end}}`

type View struct {
    Content  string
}

func main() {
    var view = &View{ "first" } // Here we try to set which page to view as content
    t := template.Must(template.New("base").Parse(base))
    t = template.Must(t.Parse(first))
    t = template.Must(t.Parse(second))
    err := t.Execute(os.Stdout, view)
    if err != nil {
        log.Println("executing template:", err)
    }
}
Run Code Online (Sandbox Code Playgroud)

play.golang.org上的代码