skeleton/internal/templates/templates.go

107 lines
2.6 KiB
Go

package templates
import (
"errors"
"html/template"
"log"
"net/http"
"path"
"path/filepath"
"strings"
"github.com/shurcooL/httpfs/html/vfstemplate"
"github.com/shurcooL/httpfs/path/vfspath"
)
// Templates contains a map of filenames to parsed and prepared templates
type Templates map[string]*template.Template
// LoadTemplatesFS takes a filesystem and a location, and returns a Templates
// map
func LoadTemplatesFS(fs http.FileSystem, dir string) Templates {
var templates = make(map[string]*template.Template)
layouts, err := vfspath.Glob(fs, dir+"/layouts/*.tmpl")
if err != nil {
log.Fatal(err)
}
//log.Printf("Loaded %d layouts", len(layouts))
includes, err := vfspath.Glob(fs, dir+"/includes/*.tmpl")
if err != nil {
log.Fatal(err)
}
//log.Printf("Loaded %d includes", len(includes))
funcs := getFuncMap() // generate function map
// Generate our templates map from our layouts/ and includes/ directories
for _, layout := range layouts {
files := append(includes, layout)
t := template.New(filepath.Base(layout)).Funcs(funcs)
t, err := vfstemplate.ParseFiles(fs, t, files...)
if err != nil {
log.Fatalf("Error parsing template %s: %s",
filepath.Base(layout), err)
}
templates[filepath.Base(layout)] = t
}
return templates
}
func (templates Templates) Get(name string) *template.Template {
t, ok := templates[name]
if !ok {
log.Printf("Error loading template %s", name)
return template.Must(template.New("empty").Parse("ERROR: Template missing"))
}
return t
}
func getFuncMap() template.FuncMap {
return template.FuncMap{
"istrue": func(value bool) bool {
return value
},
"join": func(sep string, a []string) string {
return strings.Join(a, sep)
},
"dict": func(values ...interface{}) (map[string]interface{}, error) {
if len(values)%2 != 0 {
return nil, errors.New("invalid dict call")
}
dict := make(map[string]interface{}, len(values)/2)
for i := 0; i < len(values); i += 2 {
key, ok := values[i].(string)
if !ok {
return nil, errors.New("dict keys must be strings")
}
dict[key] = values[i+1]
}
return dict, nil
},
"url": func(rel ...string) string {
params := []string{"/"}
params = append(params, rel...)
return path.Join(params...)
},
"static": func(rel ...string) string {
params := []string{"/static"}
params = append(params, rel...)
return path.Join(params...)
},
"i18n": func(locale, key string) string {
switch locale {
case "de":
return "Hallo Welt!"
case "en":
return "Hello World!"
default:
log.Printf("I18n: '%s' has no key '%s'", locale, key)
return key
}
},
}
}