我需要将模板渲染成不同类型的布局。这是我的目录结构。
<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
答案 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>
以下是完整代码的链接: