diff --git a/template/bundle/template.go b/template/bundle/template.go index 8ce8561c0..2137d0187 100644 --- a/template/bundle/template.go +++ b/template/bundle/template.go @@ -1,235 +1,244 @@ package bundle import ( - "errors" - "github.com/eknkc/amber" - "github.com/spf13/hugo/helpers" - "html" - "html/template" - "io" - "io/ioutil" - "os" - "path/filepath" - "reflect" - "strconv" - "strings" + "errors" + "github.com/eknkc/amber" + "github.com/spf13/hugo/helpers" + "html" + "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) + 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) - } + 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) + 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) - } + 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 + return left > right } // First is exposed to templates, to iterate over the first N items in a // rangeable list. func First(limit int, seq interface{}) (interface{}, error) { - if limit < 1 { - return nil, errors.New("can't return negative/empty count of items from sequence") - } + if limit < 1 { + return nil, errors.New("can't return negative/empty count of items from sequence") + } - seqv := reflect.ValueOf(seq) - // this is better than my first pass; ripped from text/template/exec.go indirect(): - for ; seqv.Kind() == reflect.Ptr || seqv.Kind() == reflect.Interface; seqv = seqv.Elem() { - if seqv.IsNil() { - return nil, errors.New("can't iterate over a nil value") - } - if seqv.Kind() == reflect.Interface && seqv.NumMethod() > 0 { - break - } - } + seqv := reflect.ValueOf(seq) + // this is better than my first pass; ripped from text/template/exec.go indirect(): + for ; seqv.Kind() == reflect.Ptr || seqv.Kind() == reflect.Interface; seqv = seqv.Elem() { + if seqv.IsNil() { + return nil, errors.New("can't iterate over a nil value") + } + if seqv.Kind() == reflect.Interface && seqv.NumMethod() > 0 { + break + } + } - switch seqv.Kind() { - case reflect.Array, reflect.Slice, reflect.String: - // okay - default: - return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String()) - } - if limit > seqv.Len() { - limit = seqv.Len() - } - return seqv.Slice(0, limit).Interface(), nil + switch seqv.Kind() { + case reflect.Array, reflect.Slice, reflect.String: + // okay + default: + return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String()) + } + if limit > seqv.Len() { + limit = seqv.Len() + } + return seqv.Slice(0, limit).Interface(), nil } func IsSet(a interface{}, key interface{}) bool { - av := reflect.ValueOf(a) - kv := reflect.ValueOf(key) + 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() - } - } + 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 + return false } func ReturnWhenSet(a interface{}, index int) interface{} { - av := reflect.ValueOf(a) + av := reflect.ValueOf(a) - switch av.Kind() { - case reflect.Array, reflect.Slice: - if av.Len() > index { + 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() - } - } - } + 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 "" + return "" } func Highlight(in interface{}, lang string) template.HTML { - var str string - av := reflect.ValueOf(in) - switch av.Kind() { - case reflect.String: - str = av.String() - } + var str string + av := reflect.ValueOf(in) + switch av.Kind() { + case reflect.String: + str = av.String() + } - if strings.HasPrefix(strings.TrimSpace(str), "
") {
- str = str[strings.Index(str, "")+11:]
- }
- if strings.HasSuffix(strings.TrimSpace(str), "
") {
- str = str[:strings.LastIndex(str, "
")]
- }
- return template.HTML(helpers.Highlight(html.UnescapeString(str), lang))
+ if strings.HasPrefix(strings.TrimSpace(str), "") {
+ str = str[strings.Index(str, "")+11:]
+ }
+ if strings.HasSuffix(strings.TrimSpace(str), "
") {
+ str = str[:strings.LastIndex(str, "
")]
+ }
+ return template.HTML(helpers.Highlight(html.UnescapeString(str), lang))
}
func SafeHtml(text string) template.HTML {
- return template.HTML(text)
+ return template.HTML(text)
}
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
+ 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
+ name string
+ err error
}
type GoHtmlTemplate struct {
- template.Template
- errors []*templateErr
+ template.Template
+ errors []*templateErr
}
func NewTemplate() Template {
- var templates = &GoHtmlTemplate{
- Template: *template.New(""),
- errors: make([]*templateErr, 0),
- }
+ var templates = &GoHtmlTemplate{
+ Template: *template.New(""),
+ errors: make([]*templateErr, 0),
+ }
- funcMap := template.FuncMap{
- "urlize": helpers.Urlize,
- "gt": Gt,
- "isset": IsSet,
- "echoParam": ReturnWhenSet,
- "safeHtml": SafeHtml,
- "first": First,
- "highlight": Highlight,
- }
+ funcMap := template.FuncMap{
+ "urlize": helpers.Urlize,
+ "gt": Gt,
+ "isset": IsSet,
+ "echoParam": ReturnWhenSet,
+ "safeHtml": SafeHtml,
+ "first": First,
+ "highlight": Highlight,
+ }
- templates.Funcs(funcMap)
- return templates
+ templates.Funcs(funcMap)
+
+ templates.LoadEmbedded()
+ return templates
+}
+
+func (t *GoHtmlTemplate) LoadEmbedded() {
+}
+
+func (t *GoHtmlTemplate) AddInternalTemplate(prefix, name, tpl string) error {
+ return t.AddTemplate("_internal/"+prefix+"/"+name, tpl)
}
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
+ _, 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
+ 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:])
+ return filepath.ToSlash(path[len(base)+1:])
}
func ignoreDotFile(path string) bool {
- return filepath.Base(path)[0] == '.'
+ 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
- }
+ walker := func(path string, fi os.FileInfo, err error) error {
+ if err != nil {
+ return nil
+ }
- if !fi.IsDir() {
- if ignoreDotFile(path) {
- return nil
- }
+ if !fi.IsDir() {
+ if ignoreDotFile(path) {
+ return nil
+ }
- tplName := t.generateTemplateNameFrom(absPath, path)
+ 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
- }
+ 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
- }
+ // note t.New(tplName)
+ if _, err := compiler.CompileWithTemplate(t.New(tplName)); err != nil {
+ return err
+ }
- } else {
- t.AddTemplateFile(tplName, path)
- }
- }
- return nil
- }
+ } else {
+ t.AddTemplateFile(tplName, path)
+ }
+ }
+ return nil
+ }
- filepath.Walk(absPath, walker)
+ filepath.Walk(absPath, walker)
}