Go 在另一个模板中呈现一个模板,而无需每次解析它们

Go 在另一个模板中呈现一个模板,而无需每次解析它们,go,Go,我有三个这样的模板: base.html: <h1>Base.html rendered here</h1> {{template "content" .}} edit.html: {{define "content"}} ... {{end}} 我将它们存储在“模板”文件夹中 我想要的是动态地更改将在{{template“content.}}}位置呈现的模板,而无需每次解析。所以我不想要的是: func main() { http.HandleFunc("/e

我有三个这样的模板:

base.html:

<h1>Base.html rendered here</h1>
{{template "content" .}}
edit.html:

{{define "content"}}
...
{{end}}
我将它们存储在“模板”文件夹中

我想要的是动态地更改将在{{template“content.}}}位置呈现的模板,而无需每次解析。所以我不想要的是:

func main() {
   http.HandleFunc("/edit", handlerEdit)
   http.HandleFunc("/view", handlerView)
   http.ListenAndServe(":8080", nil)
}
func handlerView(w http.ResponseWriter, req *http.Request) {
   renderTemplate(w, req, "view")
}

func handlerEdit(w http.ResponseWriter, req *http.Request) {
   renderTemplate(w, req, "edit")
}

func renderTemplate(w http.ResponseWriter, req *http.Request, tmpl    string) {
   templates, err := template.ParseFiles("templates/base.html",  "templates/"+tmpl+".html")
   if err != nil {
       fmt.Println("Something goes wrong ", err)
       return
   }
   someData := &Page{Title: "QWE", Body: []byte("sample body")}
   templates.Execute(w, someData)
}
我正在查看template.ParseGlobe(),以便执行类似的操作

var templates = template.Must(template.ParseGlob("templates/*.html"))
... //and then somthing like this:
err := templates.ExecuteTemplate(w, tmpl+".html", p)

但是executeTemplate()只接收一个字符串作为模板的名称。在这种情况下,如何呈现两个或多个模板?

在调用
ExecuteTemplate
时,不要直接写入
http.ResponseWriter
,而是写入字节缓冲区,并通过调用
template.HTML
将其发送到下一个模板

var b bytes.Buffer

var templates = template.Must(template.ParseGlob("templates/*.html"))

err := templates.ExecuteTemplate(b, templ_1, p)
if err != nil { //handle err }
err := templates.ExecuteTemplate(w, templ_2, template.HTML(b.String()))
if err != nil { //handle err }
如果要使用未知数量的模板,可以使用字符串捕获中间步骤:

var strtmp string
err := templates.ExecuteTemplate(b, templ_1, p)
if err != nil { //handle err }

strtemp = b.String()  //store the output
b.Reset()             //prep buffer for next template's output

err := templates.ExecuteTemplate(b, templ_2, template.HTML(strtmp))
if err != nil { //handle err }

//... until all templates are applied

b.WriteTo(w)  //Send the final output to the ResponseWriter
编辑:正如@Zhuharev所指出的,如果视图和编辑模板的组成是固定的,那么它们可以同时引用base,而不是试图提供对视图或编辑的引用的base:

{{define "viewContent"}}
{{template "templates/base.html" .}}
...Current view.html template...
{{end}}

{{define "editContent"}}
{{template "templates/base.html" .}}
...Current edit.html template...
{{end}}

执行template to string,然后用这个stringUPD执行第二个模板:你可以从任何模板中使用
{{template“templates/base.html”。}}
,我已经试着像你说的那样做了,但结果证明我无法使用ParseGlob()或ParseFiles()解析两个同名的模板{{define“content”}。我得到一个错误,即“内容”正在被重新定义。有解决办法吗?朱哈雷夫的建议很有效。朱哈雷夫的建议是编写模板的惯用方法。如果您正在处理需要将一个模板传递到另一个模板的动态组合,请在base中定义一个模板,该模板只需将传入的HTML放入模板中即可。重命名“编辑”和“查看”以避免重复,这样就可以开始了。
{{define "viewContent"}}
{{template "templates/base.html" .}}
...Current view.html template...
{{end}}

{{define "editContent"}}
{{template "templates/base.html" .}}
...Current edit.html template...
{{end}}