dran0703 2015-09-10 13:27
浏览 33
已采纳

将一个模板渲染到另一个模板中,而无需每次都对其进行解析

I have three templates like this:

base.html:

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

view.html:

{{define "content"}}
...
{{end}}

edit.html:

{{define "content"}}
...
{{end}}

I store them in folder "templates".

What i want is to dynamically change template which will be rendered in {{template "content" .}} place, without parsing every time. So what i DO NOT want is this :

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

I was looking at the template.ParseGlobe(), in order to do something like this

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

But ExecuteTamplate() recieves only one string as template's name. How in this case i can render two and more templates?

  • 写回答

1条回答 默认 最新

  • duanbei1598 2015-09-10 19:51
    关注

    Instead of writing directly to the http.ResponseWriter on your call to ExecuteTemplate, write to a byte buffer and send that through the call to the next template by prepping it with a template.HTML call.

    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 }
    

    If you're going to use an unknown number of templates, you can capture the intermediate step with a string:

    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
    

    EDIT: As @Zhuharev pointed out, if the composition of the view and edit templates are fixed, they can both reference base rather than base trying to provide a reference to either view or edit:

    {{define "viewContent"}}
    {{template "templates/base.html" .}}
    ...Current view.html template...
    {{end}}
    
    {{define "editContent"}}
    {{template "templates/base.html" .}}
    ...Current edit.html template...
    {{end}}
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值