package tmpl import ( "html/template" "log" "net/http" "os" "path" ) // Bundle map of templates type Bundle map[string]*template.Template // Tmpl template renderer type Tmpl interface { GetTemplate(name string) *template.Template Render(w http.ResponseWriter, templateName string, data interface{}) error } // HTML rendering bundle type HTML struct { bundle Bundle } // NewHTMLTmpl load a bundle func NewHTMLTmpl(basePath string) (*HTML, error) { print(basePath) b, err := loadTemplates(basePath) if err != nil { return nil, err } return &HTML{ b, }, err } func loadTemplates(basePath string) (Bundle, error) { templates := make(Bundle) baseTmplPath := path.Join(basePath, "parts", "_layout.tmpl") baseTemplate := template.New("base") baseTemplate, err := baseTemplate.ParseFiles(baseTmplPath) if err != nil { log.Fatal(err) return nil, err } partsPath := path.Join(basePath, "pages") partsDir, err := os.Open(partsPath) if err != nil { log.Fatal(err) return nil, err } parts, err := partsDir.Readdir(-1) if err != nil { log.Fatal(err) return nil, err } for _, part := range parts { t, err := baseTemplate.Clone() if err != nil { log.Fatal(err) return nil, err } templates[part.Name()] = template.Must( t.ParseFiles(path.Join(partsPath, part.Name()))) } return templates, nil } // GetTemplate load template by name func (b *HTML) GetTemplate(name string) *template.Template { return b.bundle[name] } // Render render templates func (b *HTML) Render(w http.ResponseWriter, templateName string, data interface{}) error { tpl := b.GetTemplate(templateName) err := tpl.ExecuteTemplate(w, "base", data) if err != nil { return err } return nil }