package bundle import ( "github.com/eknkc/amber" helpers "github.com/spf13/hugo/template" "html/template" "io" "io/ioutil" "os" "path/filepath" "reflect" "strconv" "strings" ) func Gt(a interface{}, b interface{}) bool { var left, right int64 av := reflect.ValueOf(a) switch av.Kind() { case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: left = int64(av.Len()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: left = av.Int() case reflect.String: left, _ = strconv.ParseInt(av.String(), 10, 64) } bv := reflect.ValueOf(b) switch bv.Kind() { case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: right = int64(bv.Len()) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: right = bv.Int() case reflect.String: right, _ = strconv.ParseInt(bv.String(), 10, 64) } return left > right } func IsSet(a interface{}, key interface{}) bool { av := reflect.ValueOf(a) kv := reflect.ValueOf(key) switch av.Kind() { case reflect.Array, reflect.Chan, reflect.Slice: if int64(av.Len()) > kv.Int() { return true } case reflect.Map: if kv.Type() == av.Type().Key() { return av.MapIndex(kv).IsValid() } } return false } func ReturnWhenSet(a interface{}, index int) interface{} { av := reflect.ValueOf(a) switch av.Kind() { case reflect.Array, reflect.Slice: if av.Len() > index { avv := av.Index(index) switch avv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return avv.Int() case reflect.String: return avv.String() } } } return "" } type Template interface { ExecuteTemplate(wr io.Writer, name string, data interface{}) error Lookup(name string) *template.Template Templates() []*template.Template New(name string) *template.Template LoadTemplates(absPath string) AddTemplate(name, tpl string) error } type templateErr struct { name string err error } type GoHtmlTemplate struct { template.Template errors []*templateErr } func NewTemplate() Template { var templates = &GoHtmlTemplate{ Template: *template.New(""), errors: make([]*templateErr, 0), } funcMap := template.FuncMap{ "urlize": helpers.Urlize, "gt": Gt, "isset": IsSet, "echoParam": ReturnWhenSet, } templates.Funcs(funcMap) templates.primeTemplates() return templates } func (t *GoHtmlTemplate) AddTemplate(name, tpl string) error { _, err := t.New(name).Parse(tpl) if err != nil { t.errors = append(t.errors, &templateErr{name: name, err: err}) } return err } func (t *GoHtmlTemplate) AddTemplateFile(name, path string) error { b, err := ioutil.ReadFile(path) if err != nil { return err } s := string(b) _, err = t.New(name).Parse(s) if err != nil { t.errors = append(t.errors, &templateErr{name: name, err: err}) } return err } func (t *GoHtmlTemplate) generateTemplateNameFrom(base, path string) string { return filepath.ToSlash(path[len(base)+1:]) } func (t *GoHtmlTemplate) primeTemplates() { alias := "\n \n \n \n \n \n \n " alias_xhtml := "\n \n \n \n \n \n \n " t.AddTemplate("alias", alias) t.AddTemplate("alias-xhtml", alias_xhtml) } func ignoreDotFile(path string) bool { return filepath.Base(path)[0] == '.' } func (t *GoHtmlTemplate) LoadTemplates(absPath string) { walker := func(path string, fi os.FileInfo, err error) error { if err != nil { return nil } if !fi.IsDir() { if ignoreDotFile(path) { return nil } tplName := t.generateTemplateNameFrom(absPath, path) if strings.HasSuffix(path, ".amber") { compiler := amber.New() // Parse the input file if err := compiler.ParseFile(path); err != nil { return nil } // note t.New(tplName) if _, err := compiler.CompileWithTemplate(t.New(tplName)); err != nil { return err } } else { t.AddTemplateFile(tplName, path) } } return nil } filepath.Walk(absPath, walker) }