douxiaochun4964 2019-02-02 00:08
浏览 16
已采纳

如何使用通用零件渲染多个模型的模板

I have many models in my golang project with CRUD views and I want to render these with common headers and footers but can't figure out how to do it. The examples I've seen are too simplistic.

Suppose I have a template structure like this:

templates
  - layouts
    - header.tmpl
    - footer.tmpl
  - users
    - index.tmpl
    - new.tmpl
    - edit.tmpl
    - show.tmpl   
  - venues
    - index.tmpl
    - new.tmpl
    - edit.tmpl
    - show.tmpl   

How do I render these templates for a specified model with the common header and footer?

  • 写回答

1条回答 默认 最新

  • dongzhenbi8919 2019-02-02 06:43
    关注

    just a barebones solution would be the following:

    package main
    
    import (
        "fmt"
        "os"
        "text/template"
    )
    
    func main() {
        //read in one go the header, footer and all your other tmpls.
        //append to that slice every time the relevant content that you want rendered.
        alltmpls := []string{"./layouts/header.tmpl", "./layouts/footer.tmpl", "./users/index.tmpl"}
        templates, err := template.ParseFiles(alltmpls...)
        t := templates.Lookup("header.tmpl")
        t.ExecuteTemplate(os.Stdout, "header", nil)
        t = templates.Lookup("index.tmpl")
        t.ExecuteTemplate(os.Stdout, "index", nil)
        t = templates.Lookup("footer.tmpl")
        t.ExecuteTemplate(os.Stdout, "footer", nil)
    }
    

    in reality you would want a function that returns a slice of the appropriate files to populate the alltmpls variable. It should scan your directories and get all files from there to pass to ParseFiles() and then proceed to call the Lookup and ExecuteTemplate steps for every template.

    Taking this idea further, i would create a new type that would embed a template (or a slice of templates) to be annotated by a header and a footer.

    type hftemplate struct {
        template.Template
        header, footer *template.Template
    }
    
    func (h *hftemplate) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
        h.header.ExecuteTemplate(wr, "header", nil)
        err := h.ExecuteTemplate(wr, name, data)
        h.footer.ExecuteTemplate(wr, "footer", nil)
        return err
    }
    

    and of course you can turn that struct embedding into a fully fledged field of []Template to do multiple ExecuteTemplates between the header and the footer.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?