hugo/template/bundle/template.go

185 lines
3.7 KiB
Go
Raw Normal View History

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 ""
}
2013-09-09 11:43:30 +00:00
func SafeHtml(text string) template.HTML {
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
}
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,
2013-09-09 11:43:30 +00:00
"safeHtml": SafeHtml,
}
templates.Funcs(funcMap)
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 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)
}