如何在Go中将模板渲染到多个布局?

时间:2017-03-12 12:08:24

标签: go go-templates

我需要将模板渲染成不同类型的布局。这是我的目录结构。

<li repeat.for="row of router.navigation" class="${row.isActive ? 'active' : ''}">

我已经将模板渲染到单个布局模板,但是,我不能让它在多个布局上工作。这是我到目前为止所得到的:

myapp
|
│   main.go
│
├───static
│       script.js
│       style.css
│
└───templates
    │   page1.tmpl
    │   page2.tmpl
    │   page3.tmpl
    │   page4.tmpl
    │   page5.tmpl
    │
    └───layouts
            base1.tmpl
            base2.tmpl
            base3.tmpl

以下是package main import ( "html/template" "net/http" "fmt" "github.com/urfave/negroni" "github.com/oxtoacart/bpool" "path/filepath" "log" ) var ( templates map[string]*template.Template bufpool *bpool.BufferPool ) func main() { loadTemplates() mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { renderTemplate(w, "page1.tmpl",nil) }) n := negroni.New() n.Use(negroni.NewLogger()) n.UseHandler(mux) http.ListenAndServe(":8080", n) } func renderTemplate(w http.ResponseWriter, name string, data map[string]interface{}) error { tmpl, ok := templates[name] if !ok { return fmt.Errorf("The template %s does not exist.", name) } buf := bufpool.Get() defer bufpool.Put(buf) err := tmpl.ExecuteTemplate(buf, "base1.tmpl", data) if err != nil { return err } w.Header().Set("Content-Type", "text/html; charset=utf-8") buf.WriteTo(w) return nil } func loadTemplates() { if templates == nil { templates = make(map[string]*template.Template) } tmplDir := "templates/" layouts, err := filepath.Glob(tmplDir + "layouts/*.tmpl") if err != nil { log.Fatal(err) } includes, err := filepath.Glob(tmplDir + "*.tmpl") if err != nil { log.Fatal(err) } for _, include := range includes { files := append(layouts, include) templates[filepath.Base(include)] = template.Must(template.ParseFiles(files...)) } fmt.Print(includes) bufpool = bpool.NewBufferPool(64) } 的样子:

base1.tmpl

以下是{{define "base1"}} <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{{block "title" .}}{{end}}</title> </head> <body> {{template "content" .}} </body> </html> {{end}} 的样子:

page1.tmpl

1 个答案:

答案 0 :(得分:0)

我通常采用渲染两次的方法,一次用于内容,一次用于布局,这使您可以使用任何布局中的任何内容并将该决定推迟到运行时。如果其他人以不同的方式做其他方法,会对其他方法感兴趣,但这对我来说是有用的。

所以使用你发布的代码,在处理程序中这样的东西:

var overlay = true;
// ...
var g = gm('input.jpg').crop(500, 500, 10, 10);
if (overlay) {
  g = g.draw('image Over 0,0 750,750 overlay.jpg');
}
g.write('output.jpg', function (err) {
  if (err) throw err;
  console.log('Success');
});

...

renderTemplate中的

传递布局和模板,并且:

data := map[string]interface{}{
            "title": "hello world",
        }
renderTemplate(w, "base1.tmpl", "page1.tmpl", data)

布局:

// Render the template 'name' with data
buf := bufpool.Get()
err := tmpl.ExecuteTemplate(buf, name, data)
if err != nil {
    return err
}

// Set the content as a key on data (set as html as it is rendered)
data["content"] = template.HTML(buf.Bytes())
bufpool.Put(buf)

// Render the layout 'layout' with data, using template as content key
buf = bufpool.Get()
defer bufpool.Put(buf)  
err = tmpl.ExecuteTemplate(buf, layout, data)
if err != nil {
    return err
}

页:

<html>
<body>
   <h1>Base 1</h1>
   {{.content}}
</body>
</html>

以下是完整代码的链接:

https://play.golang.org/p/R2vr4keZec