shithub: hugo

Download patch

ref: be2097e1ad789eca5d893805a059d94defbe5c48
parent: 42dcaabf4f81ccd8aa831049440bb0c5d85707d6
author: bep <[email protected]>
date: Sun Apr 5 17:03:16 EDT 2015

tpl: split template.go

The template funcs get their own file. This prevents having to scroll miles to get to the template infrastructure.

--- a/tpl/template.go
+++ b/tpl/template.go
@@ -15,30 +15,22 @@
 
 import (
 	"bytes"
-	"errors"
-	"fmt"
 	"github.com/eknkc/amber"
-	"github.com/spf13/cast"
 	bp "github.com/spf13/hugo/bufferpool"
 	"github.com/spf13/hugo/helpers"
 	"github.com/spf13/hugo/hugofs"
 	jww "github.com/spf13/jwalterweatherman"
 	"github.com/yosssi/ace"
-	"html"
 	"html/template"
 	"io"
 	"io/ioutil"
 	"os"
 	"path/filepath"
-	"reflect"
-	"sort"
-	"strconv"
 	"strings"
 )
 
 var localTemplates *template.Template
 var tmpl Template
-var funcMap template.FuncMap
 
 type Template interface {
 	ExecuteTemplate(wr io.Writer, name string, data interface{}) error
@@ -93,1123 +85,6 @@
 	return templates
 }
 
-func Eq(x, y interface{}) bool {
-	normalize := func(v interface{}) interface{} {
-		vv := reflect.ValueOf(v)
-		switch vv.Kind() {
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-			return vv.Int()
-		case reflect.Float32, reflect.Float64:
-			return vv.Float()
-		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-			return vv.Uint()
-		default:
-			return v
-		}
-	}
-	x = normalize(x)
-	y = normalize(y)
-	return reflect.DeepEqual(x, y)
-}
-
-func Ne(x, y interface{}) bool {
-	return !Eq(x, y)
-}
-
-func Ge(a, b interface{}) bool {
-	left, right := compareGetFloat(a, b)
-	return left >= right
-}
-
-func Gt(a, b interface{}) bool {
-	left, right := compareGetFloat(a, b)
-	return left > right
-}
-
-func Le(a, b interface{}) bool {
-	left, right := compareGetFloat(a, b)
-	return left <= right
-}
-
-func Lt(a, b interface{}) bool {
-	left, right := compareGetFloat(a, b)
-	return left < right
-}
-
-func compareGetFloat(a interface{}, b interface{}) (float64, float64) {
-	var left, right float64
-	var leftStr, rightStr *string
-	var err error
-	av := reflect.ValueOf(a)
-
-	switch av.Kind() {
-	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
-		left = float64(av.Len())
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		left = float64(av.Int())
-	case reflect.Float32, reflect.Float64:
-		left = av.Float()
-	case reflect.String:
-		left, err = strconv.ParseFloat(av.String(), 64)
-		if err != nil {
-			str := av.String()
-			leftStr = &str
-		}
-	}
-
-	bv := reflect.ValueOf(b)
-
-	switch bv.Kind() {
-	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
-		right = float64(bv.Len())
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		right = float64(bv.Int())
-	case reflect.Float32, reflect.Float64:
-		right = bv.Float()
-	case reflect.String:
-		right, err = strconv.ParseFloat(bv.String(), 64)
-		if err != nil {
-			str := bv.String()
-			rightStr = &str
-		}
-
-	}
-
-	switch {
-	case leftStr == nil || rightStr == nil:
-	case *leftStr < *rightStr:
-		return 0, 1
-	case *leftStr > *rightStr:
-		return 1, 0
-	default:
-		return 0, 0
-	}
-
-	return left, right
-}
-
-// Slicing in Slicestr is done by specifying a half-open range with
-// two indices, start and end. 1 and 4 creates a slice including elements 1 through 3.
-// The end index can be omitted, it defaults to the string's length.
-func Slicestr(a interface{}, startEnd ...int) (string, error) {
-	aStr, err := cast.ToStringE(a)
-	if err != nil {
-		return "", err
-	}
-
-	if len(startEnd) > 2 {
-		return "", errors.New("too many arguments")
-	}
-
-	if len(startEnd) == 2 {
-		return aStr[startEnd[0]:startEnd[1]], nil
-	} else if len(startEnd) == 1 {
-		return aStr[startEnd[0]:], nil
-	} else {
-		return aStr[:], nil
-	}
-
-}
-
-// Substr extracts parts of a string, beginning at the character at the specified
-// position, and returns the specified number of characters.
-//
-// It normally takes two parameters: start and length.
-// It can also take one parameter: start, i.e. length is omitted, in which case
-// the substring starting from start until the end of the string will be returned.
-//
-// To extract characters from the end of the string, use a negative start number.
-//
-// In addition, borrowing from the extended behavior described at http://php.net/substr,
-// if length is given and is negative, then that many characters will be omitted from
-// the end of string.
-func Substr(a interface{}, nums ...int) (string, error) {
-	aStr, err := cast.ToStringE(a)
-	if err != nil {
-		return "", err
-	}
-
-	var start, length int
-	switch len(nums) {
-	case 1:
-		start = nums[0]
-		length = len(aStr)
-	case 2:
-		start = nums[0]
-		length = nums[1]
-	default:
-		return "", errors.New("too many arguments")
-	}
-
-	if start < -len(aStr) {
-		start = 0
-	}
-	if start > len(aStr) {
-		return "", errors.New(fmt.Sprintf("start position out of bounds for %d-byte string", len(aStr)))
-	}
-
-	var s, e int
-	if start >= 0 && length >= 0 {
-		s = start
-		e = start + length
-	} else if start < 0 && length >= 0 {
-		s = len(aStr) + start - length + 1
-		e = len(aStr) + start + 1
-	} else if start >= 0 && length < 0 {
-		s = start
-		e = len(aStr) + length
-	} else {
-		s = len(aStr) + start
-		e = len(aStr) + length
-	}
-
-	if s > e {
-		return "", errors.New(fmt.Sprintf("calculated start position greater than end position: %d > %d", s, e))
-	}
-	if e > len(aStr) {
-		e = len(aStr)
-	}
-
-	return aStr[s:e], nil
-
-}
-
-func Split(a interface{}, delimiter string) ([]string, error) {
-	aStr, err := cast.ToStringE(a)
-	if err != nil {
-		return []string{}, err
-	}
-	return strings.Split(aStr, delimiter), nil
-}
-
-func Intersect(l1, l2 interface{}) (interface{}, error) {
-	if l1 == nil || l2 == nil {
-		return make([]interface{}, 0), nil
-	}
-
-	l1v := reflect.ValueOf(l1)
-	l2v := reflect.ValueOf(l2)
-
-	switch l1v.Kind() {
-	case reflect.Array, reflect.Slice:
-		switch l2v.Kind() {
-		case reflect.Array, reflect.Slice:
-			r := reflect.MakeSlice(l1v.Type(), 0, 0)
-			for i := 0; i < l1v.Len(); i++ {
-				l1vv := l1v.Index(i)
-				for j := 0; j < l2v.Len(); j++ {
-					l2vv := l2v.Index(j)
-					switch l1vv.Kind() {
-					case reflect.String:
-						if l1vv.Type() == l2vv.Type() && l1vv.String() == l2vv.String() && !In(r, l2vv) {
-							r = reflect.Append(r, l2vv)
-						}
-					case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-						switch l2vv.Kind() {
-						case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-							if l1vv.Int() == l2vv.Int() && !In(r, l2vv) {
-								r = reflect.Append(r, l2vv)
-							}
-						}
-					case reflect.Float32, reflect.Float64:
-						switch l2vv.Kind() {
-						case reflect.Float32, reflect.Float64:
-							if l1vv.Float() == l2vv.Float() && !In(r, l2vv) {
-								r = reflect.Append(r, l2vv)
-							}
-						}
-					}
-				}
-			}
-			return r.Interface(), nil
-		default:
-			return nil, errors.New("can't iterate over " + reflect.ValueOf(l2).Type().String())
-		}
-	default:
-		return nil, errors.New("can't iterate over " + reflect.ValueOf(l1).Type().String())
-	}
-}
-
-func In(l interface{}, v interface{}) bool {
-	lv := reflect.ValueOf(l)
-	vv := reflect.ValueOf(v)
-
-	switch lv.Kind() {
-	case reflect.Array, reflect.Slice:
-		for i := 0; i < lv.Len(); i++ {
-			lvv := lv.Index(i)
-			switch lvv.Kind() {
-			case reflect.String:
-				if vv.Type() == lvv.Type() && vv.String() == lvv.String() {
-					return true
-				}
-			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-				switch vv.Kind() {
-				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-					if vv.Int() == lvv.Int() {
-						return true
-					}
-				}
-			case reflect.Float32, reflect.Float64:
-				switch vv.Kind() {
-				case reflect.Float32, reflect.Float64:
-					if vv.Float() == lvv.Float() {
-						return true
-					}
-				}
-			}
-		}
-	case reflect.String:
-		if vv.Type() == lv.Type() && strings.Contains(lv.String(), vv.String()) {
-			return true
-		}
-	}
-	return false
-}
-
-// indirect is taken from 'text/template/exec.go'
-func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
-	for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
-		if v.IsNil() {
-			return v, true
-		}
-		if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
-			break
-		}
-	}
-	return v, false
-}
-
-// First is exposed to templates, to iterate over the first N items in a
-// rangeable list.
-func First(limit interface{}, seq interface{}) (interface{}, error) {
-
-	if limit == nil || seq == nil {
-		return nil, errors.New("both limit and seq must be provided")
-	}
-
-	limitv, err := cast.ToIntE(limit)
-
-	if err != nil {
-		return nil, err
-	}
-
-	if limitv < 1 {
-		return nil, errors.New("can't return negative/empty count of items from sequence")
-	}
-
-	seqv := reflect.ValueOf(seq)
-	seqv, isNil := indirect(seqv)
-	if isNil {
-		return nil, errors.New("can't iterate over a nil value")
-	}
-
-	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 limitv > seqv.Len() {
-		limitv = seqv.Len()
-	}
-	return seqv.Slice(0, limitv).Interface(), nil
-}
-
-var (
-	zero      reflect.Value
-	errorType = reflect.TypeOf((*error)(nil)).Elem()
-)
-
-func evaluateSubElem(obj reflect.Value, elemName string) (reflect.Value, error) {
-	if !obj.IsValid() {
-		return zero, errors.New("can't evaluate an invalid value")
-	}
-	typ := obj.Type()
-	obj, isNil := indirect(obj)
-
-	// first, check whether obj has a method. In this case, obj is
-	// an interface, a struct or its pointer. If obj is a struct,
-	// to check all T and *T method, use obj pointer type Value
-	objPtr := obj
-	if objPtr.Kind() != reflect.Interface && objPtr.CanAddr() {
-		objPtr = objPtr.Addr()
-	}
-	mt, ok := objPtr.Type().MethodByName(elemName)
-	if ok {
-		if mt.PkgPath != "" {
-			return zero, fmt.Errorf("%s is an unexported method of type %s", elemName, typ)
-		}
-		// struct pointer has one receiver argument and interface doesn't have an argument
-		if mt.Type.NumIn() > 1 || mt.Type.NumOut() == 0 || mt.Type.NumOut() > 2 {
-			return zero, fmt.Errorf("%s is a method of type %s but doesn't satisfy requirements", elemName, typ)
-		}
-		if mt.Type.NumOut() == 1 && mt.Type.Out(0).Implements(errorType) {
-			return zero, fmt.Errorf("%s is a method of type %s but doesn't satisfy requirements", elemName, typ)
-		}
-		if mt.Type.NumOut() == 2 && !mt.Type.Out(1).Implements(errorType) {
-			return zero, fmt.Errorf("%s is a method of type %s but doesn't satisfy requirements", elemName, typ)
-		}
-		res := objPtr.Method(mt.Index).Call([]reflect.Value{})
-		if len(res) == 2 && !res[1].IsNil() {
-			return zero, fmt.Errorf("error at calling a method %s of type %s: %s", elemName, typ, res[1].Interface().(error))
-		}
-		return res[0], nil
-	}
-
-	// elemName isn't a method so next start to check whether it is
-	// a struct field or a map value. In both cases, it mustn't be
-	// a nil value
-	if isNil {
-		return zero, fmt.Errorf("can't evaluate a nil pointer of type %s by a struct field or map key name %s", typ, elemName)
-	}
-	switch obj.Kind() {
-	case reflect.Struct:
-		ft, ok := obj.Type().FieldByName(elemName)
-		if ok {
-			if ft.PkgPath != "" {
-				return zero, fmt.Errorf("%s is an unexported field of struct type %s", elemName, typ)
-			}
-			return obj.FieldByIndex(ft.Index), nil
-		}
-		return zero, fmt.Errorf("%s isn't a field of struct type %s", elemName, typ)
-	case reflect.Map:
-		kv := reflect.ValueOf(elemName)
-		if kv.Type().AssignableTo(obj.Type().Key()) {
-			return obj.MapIndex(kv), nil
-		}
-		return zero, fmt.Errorf("%s isn't a key of map type %s", elemName, typ)
-	}
-	return zero, fmt.Errorf("%s is neither a struct field, a method nor a map element of type %s", elemName, typ)
-}
-
-func checkCondition(v, mv reflect.Value, op string) (bool, error) {
-	if !v.IsValid() || !mv.IsValid() {
-		return false, nil
-	}
-
-	var isNil bool
-	v, isNil = indirect(v)
-	if isNil {
-		return false, nil
-	}
-	mv, isNil = indirect(mv)
-	if isNil {
-		return false, nil
-	}
-
-	var ivp, imvp *int64
-	var svp, smvp *string
-	var ima []int64
-	var sma []string
-	if mv.Type() == v.Type() {
-		switch v.Kind() {
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-			iv := v.Int()
-			ivp = &iv
-			imv := mv.Int()
-			imvp = &imv
-		case reflect.String:
-			sv := v.String()
-			svp = &sv
-			smv := mv.String()
-			smvp = &smv
-		}
-	} else {
-		if mv.Kind() != reflect.Array && mv.Kind() != reflect.Slice {
-			return false, nil
-		}
-		if mv.Type().Elem() != v.Type() {
-			return false, nil
-		}
-		switch v.Kind() {
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-			iv := v.Int()
-			ivp = &iv
-			for i := 0; i < mv.Len(); i++ {
-				ima = append(ima, mv.Index(i).Int())
-			}
-		case reflect.String:
-			sv := v.String()
-			svp = &sv
-			for i := 0; i < mv.Len(); i++ {
-				sma = append(sma, mv.Index(i).String())
-			}
-		}
-	}
-
-	switch op {
-	case "", "=", "==", "eq":
-		if ivp != nil && imvp != nil {
-			return *ivp == *imvp, nil
-		} else if svp != nil && smvp != nil {
-			return *svp == *smvp, nil
-		}
-	case "!=", "<>", "ne":
-		if ivp != nil && imvp != nil {
-			return *ivp != *imvp, nil
-		} else if svp != nil && smvp != nil {
-			return *svp != *smvp, nil
-		}
-	case ">=", "ge":
-		if ivp != nil && imvp != nil {
-			return *ivp >= *imvp, nil
-		} else if svp != nil && smvp != nil {
-			return *svp >= *smvp, nil
-		}
-	case ">", "gt":
-		if ivp != nil && imvp != nil {
-			return *ivp > *imvp, nil
-		} else if svp != nil && smvp != nil {
-			return *svp > *smvp, nil
-		}
-	case "<=", "le":
-		if ivp != nil && imvp != nil {
-			return *ivp <= *imvp, nil
-		} else if svp != nil && smvp != nil {
-			return *svp <= *smvp, nil
-		}
-	case "<", "lt":
-		if ivp != nil && imvp != nil {
-			return *ivp < *imvp, nil
-		} else if svp != nil && smvp != nil {
-			return *svp < *smvp, nil
-		}
-	case "in", "not in":
-		var r bool
-		if ivp != nil && len(ima) > 0 {
-			r = In(ima, *ivp)
-		} else if svp != nil {
-			if len(sma) > 0 {
-				r = In(sma, *svp)
-			} else if smvp != nil {
-				r = In(*smvp, *svp)
-			}
-		} else {
-			return false, nil
-		}
-		if op == "not in" {
-			return !r, nil
-		} else {
-			return r, nil
-		}
-	default:
-		return false, errors.New("no such an operator")
-	}
-	return false, nil
-}
-
-func Where(seq, key interface{}, args ...interface{}) (r interface{}, err error) {
-	seqv := reflect.ValueOf(seq)
-	kv := reflect.ValueOf(key)
-
-	var mv reflect.Value
-	var op string
-	switch len(args) {
-	case 1:
-		mv = reflect.ValueOf(args[0])
-	case 2:
-		var ok bool
-		if op, ok = args[0].(string); !ok {
-			return nil, errors.New("operator argument must be string type")
-		}
-		op = strings.TrimSpace(strings.ToLower(op))
-		mv = reflect.ValueOf(args[1])
-	default:
-		return nil, errors.New("can't evaluate the array by no match argument or more than or equal to two arguments")
-	}
-
-	seqv, isNil := indirect(seqv)
-	if isNil {
-		return nil, errors.New("can't iterate over a nil value of type " + reflect.ValueOf(seq).Type().String())
-	}
-
-	var path []string
-	if kv.Kind() == reflect.String {
-		path = strings.Split(strings.Trim(kv.String(), "."), ".")
-	}
-
-	switch seqv.Kind() {
-	case reflect.Array, reflect.Slice:
-		rv := reflect.MakeSlice(seqv.Type(), 0, 0)
-		for i := 0; i < seqv.Len(); i++ {
-			var vvv reflect.Value
-			rvv := seqv.Index(i)
-			if kv.Kind() == reflect.String {
-				vvv = rvv
-				for _, elemName := range path {
-					vvv, err = evaluateSubElem(vvv, elemName)
-					if err != nil {
-						return nil, err
-					}
-				}
-			} else {
-				vv, _ := indirect(rvv)
-				if vv.Kind() == reflect.Map && kv.Type().AssignableTo(vv.Type().Key()) {
-					vvv = vv.MapIndex(kv)
-				}
-			}
-			if ok, err := checkCondition(vvv, mv, op); ok {
-				rv = reflect.Append(rv, rvv)
-			} else if err != nil {
-				return nil, err
-			}
-		}
-		return rv.Interface(), nil
-	default:
-		return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
-	}
-}
-
-// Apply, given a map, array, or slice, returns a new slice with the function fname applied over it.
-func Apply(seq interface{}, fname string, args ...interface{}) (interface{}, error) {
-	if seq == nil {
-		return make([]interface{}, 0), nil
-	}
-
-	if fname == "apply" {
-		return nil, errors.New("can't apply myself (no turtles allowed)")
-	}
-
-	seqv := reflect.ValueOf(seq)
-	seqv, isNil := indirect(seqv)
-	if isNil {
-		return nil, errors.New("can't iterate over a nil value")
-	}
-
-	fn, found := funcMap[fname]
-	if !found {
-		return nil, errors.New("can't find function " + fname)
-	}
-
-	fnv := reflect.ValueOf(fn)
-
-	switch seqv.Kind() {
-	case reflect.Array, reflect.Slice:
-		r := make([]interface{}, seqv.Len())
-		for i := 0; i < seqv.Len(); i++ {
-			vv := seqv.Index(i)
-
-			vvv, err := applyFnToThis(fnv, vv, args...)
-
-			if err != nil {
-				return nil, err
-			}
-
-			r[i] = vvv.Interface()
-		}
-
-		return r, nil
-	default:
-		return nil, errors.New("can't apply over " + reflect.ValueOf(seq).Type().String())
-	}
-}
-
-func applyFnToThis(fn, this reflect.Value, args ...interface{}) (reflect.Value, error) {
-	n := make([]reflect.Value, len(args))
-	for i, arg := range args {
-		if arg == "." {
-			n[i] = this
-		} else {
-			n[i] = reflect.ValueOf(arg)
-		}
-	}
-
-	res := fn.Call(n)
-
-	if len(res) == 1 || res[1].IsNil() {
-		return res[0], nil
-	} else {
-		return reflect.ValueOf(nil), res[1].Interface().(error)
-	}
-}
-
-func Delimit(seq, delimiter interface{}, last ...interface{}) (template.HTML, error) {
-	d, err := cast.ToStringE(delimiter)
-	if err != nil {
-		return "", err
-	}
-
-	var dLast *string
-	for _, l := range last {
-		dStr, err := cast.ToStringE(l)
-		if err != nil {
-			dLast = nil
-		}
-		dLast = &dStr
-		break
-	}
-
-	seqv := reflect.ValueOf(seq)
-	seqv, isNil := indirect(seqv)
-	if isNil {
-		return "", errors.New("can't iterate over a nil value")
-	}
-
-	var str string
-	switch seqv.Kind() {
-	case reflect.Map:
-		sortSeq, err := Sort(seq)
-		if err != nil {
-			return "", err
-		}
-		seqv = reflect.ValueOf(sortSeq)
-		fallthrough
-	case reflect.Array, reflect.Slice, reflect.String:
-		for i := 0; i < seqv.Len(); i++ {
-			val := seqv.Index(i).Interface()
-			valStr, err := cast.ToStringE(val)
-			if err != nil {
-				continue
-			}
-			switch {
-			case i == seqv.Len()-2 && dLast != nil:
-				str += valStr + *dLast
-			case i == seqv.Len()-1:
-				str += valStr
-			default:
-				str += valStr + d
-			}
-		}
-
-	default:
-		return "", errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
-	}
-
-	return template.HTML(str), nil
-}
-
-func Sort(seq interface{}, args ...interface{}) ([]interface{}, error) {
-	seqv := reflect.ValueOf(seq)
-	seqv, isNil := indirect(seqv)
-	if isNil {
-		return nil, errors.New("can't iterate over a nil value")
-	}
-
-	// Create a list of pairs that will be used to do the sort
-	p := pairList{SortAsc: true}
-	p.Pairs = make([]pair, seqv.Len())
-
-	for i, l := range args {
-		dStr, err := cast.ToStringE(l)
-		switch {
-		case i == 0 && err != nil:
-			p.SortByField = ""
-		case i == 0 && err == nil:
-			p.SortByField = dStr
-		case i == 1 && err == nil && dStr == "desc":
-			p.SortAsc = false
-		case i == 1:
-			p.SortAsc = true
-		}
-	}
-
-	var sorted []interface{}
-	switch seqv.Kind() {
-	case reflect.Array, reflect.Slice:
-		for i := 0; i < seqv.Len(); i++ {
-			p.Pairs[i].Key = reflect.ValueOf(i)
-			p.Pairs[i].Value = seqv.Index(i)
-		}
-		if p.SortByField == "" {
-			p.SortByField = "value"
-		}
-
-	case reflect.Map:
-		keys := seqv.MapKeys()
-		for i := 0; i < seqv.Len(); i++ {
-			p.Pairs[i].Key = keys[i]
-			p.Pairs[i].Value = seqv.MapIndex(keys[i])
-		}
-
-	default:
-		return nil, errors.New("can't sort " + reflect.ValueOf(seq).Type().String())
-	}
-	sorted = p.sort()
-	return sorted, nil
-}
-
-// Credit for pair sorting method goes to Andrew Gerrand
-// https://groups.google.com/forum/#!topic/golang-nuts/FT7cjmcL7gw
-// A data structure to hold a key/value pair.
-type pair struct {
-	Key   reflect.Value
-	Value reflect.Value
-}
-
-// A slice of pairs that implements sort.Interface to sort by Value.
-type pairList struct {
-	Pairs       []pair
-	SortByField string
-	SortAsc     bool
-}
-
-func (p pairList) Swap(i, j int) { p.Pairs[i], p.Pairs[j] = p.Pairs[j], p.Pairs[i] }
-func (p pairList) Len() int      { return len(p.Pairs) }
-func (p pairList) Less(i, j int) bool {
-	var truth bool
-	switch {
-	case p.SortByField == "value":
-		iVal := p.Pairs[i].Value
-		jVal := p.Pairs[j].Value
-		truth = Lt(iVal.Interface(), jVal.Interface())
-
-	case p.SortByField != "":
-		if p.Pairs[i].Value.FieldByName(p.SortByField).IsValid() {
-			iVal := p.Pairs[i].Value.FieldByName(p.SortByField)
-			jVal := p.Pairs[j].Value.FieldByName(p.SortByField)
-			truth = Lt(iVal.Interface(), jVal.Interface())
-		}
-	default:
-		iVal := p.Pairs[i].Key
-		jVal := p.Pairs[j].Key
-		truth = Lt(iVal.Interface(), jVal.Interface())
-	}
-	return truth
-}
-
-// sorts a pairList and returns a slice of sorted values
-func (p pairList) sort() []interface{} {
-	if p.SortAsc {
-		sort.Sort(p)
-	} else {
-		sort.Sort(sort.Reverse(p))
-	}
-	sorted := make([]interface{}, len(p.Pairs))
-	for i, v := range p.Pairs {
-		sorted[i] = v.Value.Interface()
-	}
-
-	return sorted
-}
-
-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, k interface{}) interface{} {
-	av, isNil := indirect(reflect.ValueOf(a))
-	if isNil {
-		return ""
-	}
-
-	var avv reflect.Value
-	switch av.Kind() {
-	case reflect.Array, reflect.Slice:
-		index, ok := k.(int)
-		if ok && av.Len() > index {
-			avv = av.Index(index)
-		}
-	case reflect.Map:
-		kv := reflect.ValueOf(k)
-		if kv.Type().AssignableTo(av.Type().Key()) {
-			avv = av.MapIndex(kv)
-		}
-	}
-
-	if avv.IsValid() {
-		switch avv.Kind() {
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-			return avv.Int()
-		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-			return avv.Uint()
-		case reflect.Float32, reflect.Float64:
-			return avv.Float()
-		case reflect.String:
-			return avv.String()
-		}
-	}
-
-	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()
-	}
-
-	return template.HTML(helpers.Highlight(html.UnescapeString(str), lang))
-}
-
-var markdownTrimPrefix = []byte("<p>")
-var markdownTrimSuffix = []byte("</p>\n")
-
-func Markdownify(text string) template.HTML {
-	m := helpers.RenderBytes(&helpers.RenderingContext{Content: []byte(text), PageFmt: "markdown"})
-	m = bytes.TrimPrefix(m, markdownTrimPrefix)
-	m = bytes.TrimSuffix(m, markdownTrimSuffix)
-	return template.HTML(m)
-}
-
-func refPage(page interface{}, ref, methodName string) template.HTML {
-	value := reflect.ValueOf(page)
-
-	method := value.MethodByName(methodName)
-
-	if method.IsValid() && method.Type().NumIn() == 1 && method.Type().NumOut() == 2 {
-		result := method.Call([]reflect.Value{reflect.ValueOf(ref)})
-
-		url, err := result[0], result[1]
-
-		if !err.IsNil() {
-			jww.ERROR.Printf("%s", err.Interface())
-			return template.HTML(fmt.Sprintf("%s", err.Interface()))
-		}
-
-		if url.String() == "" {
-			jww.ERROR.Printf("ref %s could not be found\n", ref)
-			return template.HTML(ref)
-		}
-
-		return template.HTML(url.String())
-	}
-
-	jww.ERROR.Printf("Can only create references from Page and Node objects.")
-	return template.HTML(ref)
-}
-
-func Ref(page interface{}, ref string) template.HTML {
-	return refPage(page, ref, "Ref")
-}
-
-func RelRef(page interface{}, ref string) template.HTML {
-	return refPage(page, ref, "RelRef")
-}
-
-func Chomp(text interface{}) (string, error) {
-	s, err := cast.ToStringE(text)
-	if err != nil {
-		return "", err
-	}
-
-	return strings.TrimRight(s, "\r\n"), nil
-}
-
-// Trim leading/trailing characters defined by b from a
-func Trim(a interface{}, b string) (string, error) {
-	aStr, err := cast.ToStringE(a)
-	if err != nil {
-		return "", err
-	}
-	return strings.Trim(aStr, b), nil
-}
-
-// Replace all occurences of b with c in a
-func Replace(a, b, c interface{}) (string, error) {
-	aStr, err := cast.ToStringE(a)
-	if err != nil {
-		return "", err
-	}
-	bStr, err := cast.ToStringE(b)
-	if err != nil {
-		return "", err
-	}
-	cStr, err := cast.ToStringE(c)
-	if err != nil {
-		return "", err
-	}
-	return strings.Replace(aStr, bStr, cStr, -1), nil
-}
-
-// DateFormat converts the textual representation of the datetime string into
-// the other form or returns it of the time.Time value. These are formatted
-// with the layout string
-func DateFormat(layout string, v interface{}) (string, error) {
-	t, err := cast.ToTimeE(v)
-	if err != nil {
-		return "", err
-	}
-	return t.Format(layout), nil
-}
-
-func SafeHTML(text string) template.HTML {
-	return template.HTML(text)
-}
-
-// "safeHTMLAttr" is currently disabled, pending further discussion
-// on its use case.  2015-01-19
-func SafeHTMLAttr(text string) template.HTMLAttr {
-	return template.HTMLAttr(text)
-}
-
-func SafeCSS(text string) template.CSS {
-	return template.CSS(text)
-}
-
-func SafeURL(text string) template.URL {
-	return template.URL(text)
-}
-
-func doArithmetic(a, b interface{}, op rune) (interface{}, error) {
-	av := reflect.ValueOf(a)
-	bv := reflect.ValueOf(b)
-	var ai, bi int64
-	var af, bf float64
-	var au, bu uint64
-	switch av.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		ai = av.Int()
-		switch bv.Kind() {
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-			bi = bv.Int()
-		case reflect.Float32, reflect.Float64:
-			af = float64(ai) // may overflow
-			ai = 0
-			bf = bv.Float()
-		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-			bu = bv.Uint()
-			if ai >= 0 {
-				au = uint64(ai)
-				ai = 0
-			} else {
-				bi = int64(bu) // may overflow
-				bu = 0
-			}
-		default:
-			return nil, errors.New("Can't apply the operator to the values")
-		}
-	case reflect.Float32, reflect.Float64:
-		af = av.Float()
-		switch bv.Kind() {
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-			bf = float64(bv.Int()) // may overflow
-		case reflect.Float32, reflect.Float64:
-			bf = bv.Float()
-		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-			bf = float64(bv.Uint()) // may overflow
-		default:
-			return nil, errors.New("Can't apply the operator to the values")
-		}
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		au = av.Uint()
-		switch bv.Kind() {
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-			bi = bv.Int()
-			if bi >= 0 {
-				bu = uint64(bi)
-				bi = 0
-			} else {
-				ai = int64(au) // may overflow
-				au = 0
-			}
-		case reflect.Float32, reflect.Float64:
-			af = float64(au) // may overflow
-			au = 0
-			bf = bv.Float()
-		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-			bu = bv.Uint()
-		default:
-			return nil, errors.New("Can't apply the operator to the values")
-		}
-	case reflect.String:
-		as := av.String()
-		if bv.Kind() == reflect.String && op == '+' {
-			bs := bv.String()
-			return as + bs, nil
-		} else {
-			return nil, errors.New("Can't apply the operator to the values")
-		}
-	default:
-		return nil, errors.New("Can't apply the operator to the values")
-	}
-
-	switch op {
-	case '+':
-		if ai != 0 || bi != 0 {
-			return ai + bi, nil
-		} else if af != 0 || bf != 0 {
-			return af + bf, nil
-		} else if au != 0 || bu != 0 {
-			return au + bu, nil
-		} else {
-			return 0, nil
-		}
-	case '-':
-		if ai != 0 || bi != 0 {
-			return ai - bi, nil
-		} else if af != 0 || bf != 0 {
-			return af - bf, nil
-		} else if au != 0 || bu != 0 {
-			return au - bu, nil
-		} else {
-			return 0, nil
-		}
-	case '*':
-		if ai != 0 || bi != 0 {
-			return ai * bi, nil
-		} else if af != 0 || bf != 0 {
-			return af * bf, nil
-		} else if au != 0 || bu != 0 {
-			return au * bu, nil
-		} else {
-			return 0, nil
-		}
-	case '/':
-		if bi != 0 {
-			return ai / bi, nil
-		} else if bf != 0 {
-			return af / bf, nil
-		} else if bu != 0 {
-			return au / bu, nil
-		} else {
-			return nil, errors.New("Can't divide the value by 0")
-		}
-	default:
-		return nil, errors.New("There is no such an operation")
-	}
-}
-
-func Mod(a, b interface{}) (int64, error) {
-	av := reflect.ValueOf(a)
-	bv := reflect.ValueOf(b)
-	var ai, bi int64
-
-	switch av.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		ai = av.Int()
-	default:
-		return 0, errors.New("Modulo operator can't be used with non integer value")
-	}
-
-	switch bv.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		bi = bv.Int()
-	default:
-		return 0, errors.New("Modulo operator can't be used with non integer value")
-	}
-
-	if bi == 0 {
-		return 0, errors.New("The number can't be divided by zero at modulo operation")
-	}
-
-	return ai % bi, nil
-}
-
-func ModBool(a, b interface{}) (bool, error) {
-	res, err := Mod(a, b)
-	if err != nil {
-		return false, err
-	}
-	return res == int64(0), nil
-}
-
 func Partial(name string, context_list ...interface{}) template.HTML {
 	if strings.HasPrefix("partials/", name) {
 		name = name[8:]
@@ -1351,8 +226,6 @@
 	return path[len(path)-1] == '~'
 }
 
-// TODO(bep) split this file in two => template_funcs.go + tests.
-
 const baseAceFilename = "baseof.ace"
 
 var aceTemplateInnerMarker = []byte("= content")
@@ -1440,83 +313,4 @@
 	for _, e := range t.errors {
 		jww.ERROR.Println(e.err)
 	}
-}
-
-func init() {
-	funcMap = template.FuncMap{
-		"urlize":      helpers.URLize,
-		"sanitizeURL": helpers.SanitizeURL,
-		"sanitizeurl": helpers.SanitizeURL,
-		"eq":          Eq,
-		"ne":          Ne,
-		"gt":          Gt,
-		"ge":          Ge,
-		"lt":          Lt,
-		"le":          Le,
-		"in":          In,
-		"slicestr":    Slicestr,
-		"substr":      Substr,
-		"split":       Split,
-		"intersect":   Intersect,
-		"isSet":       IsSet,
-		"isset":       IsSet,
-		"echoParam":   ReturnWhenSet,
-		"safeHTML":    SafeHTML,
-		"safeCSS":     SafeCSS,
-		"safeURL":     SafeURL,
-		"markdownify": Markdownify,
-		"first":       First,
-		"where":       Where,
-		"delimit":     Delimit,
-		"sort":        Sort,
-		"highlight":   Highlight,
-		"add":         func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '+') },
-		"sub":         func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '-') },
-		"div":         func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '/') },
-		"mod":         Mod,
-		"mul":         func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '*') },
-		"modBool":     ModBool,
-		"lower":       func(a string) string { return strings.ToLower(a) },
-		"upper":       func(a string) string { return strings.ToUpper(a) },
-		"title":       func(a string) string { return strings.Title(a) },
-		"partial":     Partial,
-		"ref":         Ref,
-		"relref":      RelRef,
-		"apply":       Apply,
-		"chomp":       Chomp,
-		"replace":     Replace,
-		"trim":        Trim,
-		"dateFormat":  DateFormat,
-		"getJSON":     GetJSON,
-		"getCSV":      GetCSV,
-		"seq":         helpers.Seq,
-		"getenv":      func(varName string) string { return os.Getenv(varName) },
-
-		// "getJson" is deprecated. Will be removed in 0.15.
-		"getJson": func(urlParts ...string) interface{} {
-			helpers.Deprecated("Template", "getJson", "getJSON")
-			return GetJSON(urlParts...)
-		},
-		// "getJson" is deprecated. Will be removed in 0.15.
-		"getCsv": func(sep string, urlParts ...string) [][]string {
-			helpers.Deprecated("Template", "getCsv", "getCSV")
-			return GetCSV(sep, urlParts...)
-		},
-		// "safeHtml" is deprecated. Will be removed in 0.15.
-		"safeHtml": func(text string) template.HTML {
-			helpers.Deprecated("Template", "safeHtml", "safeHTML")
-			return SafeHTML(text)
-		},
-		// "safeCss" is deprecated. Will be removed in 0.15.
-		"safeCss": func(text string) template.CSS {
-			helpers.Deprecated("Template", "safeCss", "safeCSS")
-			return SafeCSS(text)
-		},
-		// "safeUrl" is deprecated. Will be removed in 0.15.
-		"safeUrl": func(text string) template.URL {
-			helpers.Deprecated("Template", "safeUrl", "safeURL")
-			return SafeURL(text)
-		},
-	}
-
 }
--- /dev/null
+++ b/tpl/template_funcs.go
@@ -1,0 +1,1228 @@
+// Copyright © 2013-14 Steve Francia <[email protected]>.
+//
+// Licensed under the Simple Public License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://opensource.org/licenses/Simple-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package tpl
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"github.com/spf13/cast"
+	"github.com/spf13/hugo/helpers"
+	jww "github.com/spf13/jwalterweatherman"
+	"html"
+	"html/template"
+	"os"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+var funcMap template.FuncMap
+
+func Eq(x, y interface{}) bool {
+	normalize := func(v interface{}) interface{} {
+		vv := reflect.ValueOf(v)
+		switch vv.Kind() {
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			return vv.Int()
+		case reflect.Float32, reflect.Float64:
+			return vv.Float()
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+			return vv.Uint()
+		default:
+			return v
+		}
+	}
+	x = normalize(x)
+	y = normalize(y)
+	return reflect.DeepEqual(x, y)
+}
+
+func Ne(x, y interface{}) bool {
+	return !Eq(x, y)
+}
+
+func Ge(a, b interface{}) bool {
+	left, right := compareGetFloat(a, b)
+	return left >= right
+}
+
+func Gt(a, b interface{}) bool {
+	left, right := compareGetFloat(a, b)
+	return left > right
+}
+
+func Le(a, b interface{}) bool {
+	left, right := compareGetFloat(a, b)
+	return left <= right
+}
+
+func Lt(a, b interface{}) bool {
+	left, right := compareGetFloat(a, b)
+	return left < right
+}
+
+func compareGetFloat(a interface{}, b interface{}) (float64, float64) {
+	var left, right float64
+	var leftStr, rightStr *string
+	var err error
+	av := reflect.ValueOf(a)
+
+	switch av.Kind() {
+	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
+		left = float64(av.Len())
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		left = float64(av.Int())
+	case reflect.Float32, reflect.Float64:
+		left = av.Float()
+	case reflect.String:
+		left, err = strconv.ParseFloat(av.String(), 64)
+		if err != nil {
+			str := av.String()
+			leftStr = &str
+		}
+	}
+
+	bv := reflect.ValueOf(b)
+
+	switch bv.Kind() {
+	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:
+		right = float64(bv.Len())
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		right = float64(bv.Int())
+	case reflect.Float32, reflect.Float64:
+		right = bv.Float()
+	case reflect.String:
+		right, err = strconv.ParseFloat(bv.String(), 64)
+		if err != nil {
+			str := bv.String()
+			rightStr = &str
+		}
+
+	}
+
+	switch {
+	case leftStr == nil || rightStr == nil:
+	case *leftStr < *rightStr:
+		return 0, 1
+	case *leftStr > *rightStr:
+		return 1, 0
+	default:
+		return 0, 0
+	}
+
+	return left, right
+}
+
+// Slicing in Slicestr is done by specifying a half-open range with
+// two indices, start and end. 1 and 4 creates a slice including elements 1 through 3.
+// The end index can be omitted, it defaults to the string's length.
+func Slicestr(a interface{}, startEnd ...int) (string, error) {
+	aStr, err := cast.ToStringE(a)
+	if err != nil {
+		return "", err
+	}
+
+	if len(startEnd) > 2 {
+		return "", errors.New("too many arguments")
+	}
+
+	if len(startEnd) == 2 {
+		return aStr[startEnd[0]:startEnd[1]], nil
+	} else if len(startEnd) == 1 {
+		return aStr[startEnd[0]:], nil
+	} else {
+		return aStr[:], nil
+	}
+
+}
+
+// Substr extracts parts of a string, beginning at the character at the specified
+// position, and returns the specified number of characters.
+//
+// It normally takes two parameters: start and length.
+// It can also take one parameter: start, i.e. length is omitted, in which case
+// the substring starting from start until the end of the string will be returned.
+//
+// To extract characters from the end of the string, use a negative start number.
+//
+// In addition, borrowing from the extended behavior described at http://php.net/substr,
+// if length is given and is negative, then that many characters will be omitted from
+// the end of string.
+func Substr(a interface{}, nums ...int) (string, error) {
+	aStr, err := cast.ToStringE(a)
+	if err != nil {
+		return "", err
+	}
+
+	var start, length int
+	switch len(nums) {
+	case 1:
+		start = nums[0]
+		length = len(aStr)
+	case 2:
+		start = nums[0]
+		length = nums[1]
+	default:
+		return "", errors.New("too many arguments")
+	}
+
+	if start < -len(aStr) {
+		start = 0
+	}
+	if start > len(aStr) {
+		return "", errors.New(fmt.Sprintf("start position out of bounds for %d-byte string", len(aStr)))
+	}
+
+	var s, e int
+	if start >= 0 && length >= 0 {
+		s = start
+		e = start + length
+	} else if start < 0 && length >= 0 {
+		s = len(aStr) + start - length + 1
+		e = len(aStr) + start + 1
+	} else if start >= 0 && length < 0 {
+		s = start
+		e = len(aStr) + length
+	} else {
+		s = len(aStr) + start
+		e = len(aStr) + length
+	}
+
+	if s > e {
+		return "", errors.New(fmt.Sprintf("calculated start position greater than end position: %d > %d", s, e))
+	}
+	if e > len(aStr) {
+		e = len(aStr)
+	}
+
+	return aStr[s:e], nil
+
+}
+
+func Split(a interface{}, delimiter string) ([]string, error) {
+	aStr, err := cast.ToStringE(a)
+	if err != nil {
+		return []string{}, err
+	}
+	return strings.Split(aStr, delimiter), nil
+}
+
+func Intersect(l1, l2 interface{}) (interface{}, error) {
+	if l1 == nil || l2 == nil {
+		return make([]interface{}, 0), nil
+	}
+
+	l1v := reflect.ValueOf(l1)
+	l2v := reflect.ValueOf(l2)
+
+	switch l1v.Kind() {
+	case reflect.Array, reflect.Slice:
+		switch l2v.Kind() {
+		case reflect.Array, reflect.Slice:
+			r := reflect.MakeSlice(l1v.Type(), 0, 0)
+			for i := 0; i < l1v.Len(); i++ {
+				l1vv := l1v.Index(i)
+				for j := 0; j < l2v.Len(); j++ {
+					l2vv := l2v.Index(j)
+					switch l1vv.Kind() {
+					case reflect.String:
+						if l1vv.Type() == l2vv.Type() && l1vv.String() == l2vv.String() && !In(r, l2vv) {
+							r = reflect.Append(r, l2vv)
+						}
+					case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+						switch l2vv.Kind() {
+						case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+							if l1vv.Int() == l2vv.Int() && !In(r, l2vv) {
+								r = reflect.Append(r, l2vv)
+							}
+						}
+					case reflect.Float32, reflect.Float64:
+						switch l2vv.Kind() {
+						case reflect.Float32, reflect.Float64:
+							if l1vv.Float() == l2vv.Float() && !In(r, l2vv) {
+								r = reflect.Append(r, l2vv)
+							}
+						}
+					}
+				}
+			}
+			return r.Interface(), nil
+		default:
+			return nil, errors.New("can't iterate over " + reflect.ValueOf(l2).Type().String())
+		}
+	default:
+		return nil, errors.New("can't iterate over " + reflect.ValueOf(l1).Type().String())
+	}
+}
+
+func In(l interface{}, v interface{}) bool {
+	lv := reflect.ValueOf(l)
+	vv := reflect.ValueOf(v)
+
+	switch lv.Kind() {
+	case reflect.Array, reflect.Slice:
+		for i := 0; i < lv.Len(); i++ {
+			lvv := lv.Index(i)
+			switch lvv.Kind() {
+			case reflect.String:
+				if vv.Type() == lvv.Type() && vv.String() == lvv.String() {
+					return true
+				}
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				switch vv.Kind() {
+				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+					if vv.Int() == lvv.Int() {
+						return true
+					}
+				}
+			case reflect.Float32, reflect.Float64:
+				switch vv.Kind() {
+				case reflect.Float32, reflect.Float64:
+					if vv.Float() == lvv.Float() {
+						return true
+					}
+				}
+			}
+		}
+	case reflect.String:
+		if vv.Type() == lv.Type() && strings.Contains(lv.String(), vv.String()) {
+			return true
+		}
+	}
+	return false
+}
+
+// indirect is taken from 'text/template/exec.go'
+func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
+	for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
+		if v.IsNil() {
+			return v, true
+		}
+		if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
+			break
+		}
+	}
+	return v, false
+}
+
+// First is exposed to templates, to iterate over the first N items in a
+// rangeable list.
+func First(limit interface{}, seq interface{}) (interface{}, error) {
+
+	if limit == nil || seq == nil {
+		return nil, errors.New("both limit and seq must be provided")
+	}
+
+	limitv, err := cast.ToIntE(limit)
+
+	if err != nil {
+		return nil, err
+	}
+
+	if limitv < 1 {
+		return nil, errors.New("can't return negative/empty count of items from sequence")
+	}
+
+	seqv := reflect.ValueOf(seq)
+	seqv, isNil := indirect(seqv)
+	if isNil {
+		return nil, errors.New("can't iterate over a nil value")
+	}
+
+	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 limitv > seqv.Len() {
+		limitv = seqv.Len()
+	}
+	return seqv.Slice(0, limitv).Interface(), nil
+}
+
+var (
+	zero      reflect.Value
+	errorType = reflect.TypeOf((*error)(nil)).Elem()
+)
+
+func evaluateSubElem(obj reflect.Value, elemName string) (reflect.Value, error) {
+	if !obj.IsValid() {
+		return zero, errors.New("can't evaluate an invalid value")
+	}
+	typ := obj.Type()
+	obj, isNil := indirect(obj)
+
+	// first, check whether obj has a method. In this case, obj is
+	// an interface, a struct or its pointer. If obj is a struct,
+	// to check all T and *T method, use obj pointer type Value
+	objPtr := obj
+	if objPtr.Kind() != reflect.Interface && objPtr.CanAddr() {
+		objPtr = objPtr.Addr()
+	}
+	mt, ok := objPtr.Type().MethodByName(elemName)
+	if ok {
+		if mt.PkgPath != "" {
+			return zero, fmt.Errorf("%s is an unexported method of type %s", elemName, typ)
+		}
+		// struct pointer has one receiver argument and interface doesn't have an argument
+		if mt.Type.NumIn() > 1 || mt.Type.NumOut() == 0 || mt.Type.NumOut() > 2 {
+			return zero, fmt.Errorf("%s is a method of type %s but doesn't satisfy requirements", elemName, typ)
+		}
+		if mt.Type.NumOut() == 1 && mt.Type.Out(0).Implements(errorType) {
+			return zero, fmt.Errorf("%s is a method of type %s but doesn't satisfy requirements", elemName, typ)
+		}
+		if mt.Type.NumOut() == 2 && !mt.Type.Out(1).Implements(errorType) {
+			return zero, fmt.Errorf("%s is a method of type %s but doesn't satisfy requirements", elemName, typ)
+		}
+		res := objPtr.Method(mt.Index).Call([]reflect.Value{})
+		if len(res) == 2 && !res[1].IsNil() {
+			return zero, fmt.Errorf("error at calling a method %s of type %s: %s", elemName, typ, res[1].Interface().(error))
+		}
+		return res[0], nil
+	}
+
+	// elemName isn't a method so next start to check whether it is
+	// a struct field or a map value. In both cases, it mustn't be
+	// a nil value
+	if isNil {
+		return zero, fmt.Errorf("can't evaluate a nil pointer of type %s by a struct field or map key name %s", typ, elemName)
+	}
+	switch obj.Kind() {
+	case reflect.Struct:
+		ft, ok := obj.Type().FieldByName(elemName)
+		if ok {
+			if ft.PkgPath != "" {
+				return zero, fmt.Errorf("%s is an unexported field of struct type %s", elemName, typ)
+			}
+			return obj.FieldByIndex(ft.Index), nil
+		}
+		return zero, fmt.Errorf("%s isn't a field of struct type %s", elemName, typ)
+	case reflect.Map:
+		kv := reflect.ValueOf(elemName)
+		if kv.Type().AssignableTo(obj.Type().Key()) {
+			return obj.MapIndex(kv), nil
+		}
+		return zero, fmt.Errorf("%s isn't a key of map type %s", elemName, typ)
+	}
+	return zero, fmt.Errorf("%s is neither a struct field, a method nor a map element of type %s", elemName, typ)
+}
+
+func checkCondition(v, mv reflect.Value, op string) (bool, error) {
+	if !v.IsValid() || !mv.IsValid() {
+		return false, nil
+	}
+
+	var isNil bool
+	v, isNil = indirect(v)
+	if isNil {
+		return false, nil
+	}
+	mv, isNil = indirect(mv)
+	if isNil {
+		return false, nil
+	}
+
+	var ivp, imvp *int64
+	var svp, smvp *string
+	var ima []int64
+	var sma []string
+	if mv.Type() == v.Type() {
+		switch v.Kind() {
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			iv := v.Int()
+			ivp = &iv
+			imv := mv.Int()
+			imvp = &imv
+		case reflect.String:
+			sv := v.String()
+			svp = &sv
+			smv := mv.String()
+			smvp = &smv
+		}
+	} else {
+		if mv.Kind() != reflect.Array && mv.Kind() != reflect.Slice {
+			return false, nil
+		}
+		if mv.Type().Elem() != v.Type() {
+			return false, nil
+		}
+		switch v.Kind() {
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			iv := v.Int()
+			ivp = &iv
+			for i := 0; i < mv.Len(); i++ {
+				ima = append(ima, mv.Index(i).Int())
+			}
+		case reflect.String:
+			sv := v.String()
+			svp = &sv
+			for i := 0; i < mv.Len(); i++ {
+				sma = append(sma, mv.Index(i).String())
+			}
+		}
+	}
+
+	switch op {
+	case "", "=", "==", "eq":
+		if ivp != nil && imvp != nil {
+			return *ivp == *imvp, nil
+		} else if svp != nil && smvp != nil {
+			return *svp == *smvp, nil
+		}
+	case "!=", "<>", "ne":
+		if ivp != nil && imvp != nil {
+			return *ivp != *imvp, nil
+		} else if svp != nil && smvp != nil {
+			return *svp != *smvp, nil
+		}
+	case ">=", "ge":
+		if ivp != nil && imvp != nil {
+			return *ivp >= *imvp, nil
+		} else if svp != nil && smvp != nil {
+			return *svp >= *smvp, nil
+		}
+	case ">", "gt":
+		if ivp != nil && imvp != nil {
+			return *ivp > *imvp, nil
+		} else if svp != nil && smvp != nil {
+			return *svp > *smvp, nil
+		}
+	case "<=", "le":
+		if ivp != nil && imvp != nil {
+			return *ivp <= *imvp, nil
+		} else if svp != nil && smvp != nil {
+			return *svp <= *smvp, nil
+		}
+	case "<", "lt":
+		if ivp != nil && imvp != nil {
+			return *ivp < *imvp, nil
+		} else if svp != nil && smvp != nil {
+			return *svp < *smvp, nil
+		}
+	case "in", "not in":
+		var r bool
+		if ivp != nil && len(ima) > 0 {
+			r = In(ima, *ivp)
+		} else if svp != nil {
+			if len(sma) > 0 {
+				r = In(sma, *svp)
+			} else if smvp != nil {
+				r = In(*smvp, *svp)
+			}
+		} else {
+			return false, nil
+		}
+		if op == "not in" {
+			return !r, nil
+		} else {
+			return r, nil
+		}
+	default:
+		return false, errors.New("no such an operator")
+	}
+	return false, nil
+}
+
+func Where(seq, key interface{}, args ...interface{}) (r interface{}, err error) {
+	seqv := reflect.ValueOf(seq)
+	kv := reflect.ValueOf(key)
+
+	var mv reflect.Value
+	var op string
+	switch len(args) {
+	case 1:
+		mv = reflect.ValueOf(args[0])
+	case 2:
+		var ok bool
+		if op, ok = args[0].(string); !ok {
+			return nil, errors.New("operator argument must be string type")
+		}
+		op = strings.TrimSpace(strings.ToLower(op))
+		mv = reflect.ValueOf(args[1])
+	default:
+		return nil, errors.New("can't evaluate the array by no match argument or more than or equal to two arguments")
+	}
+
+	seqv, isNil := indirect(seqv)
+	if isNil {
+		return nil, errors.New("can't iterate over a nil value of type " + reflect.ValueOf(seq).Type().String())
+	}
+
+	var path []string
+	if kv.Kind() == reflect.String {
+		path = strings.Split(strings.Trim(kv.String(), "."), ".")
+	}
+
+	switch seqv.Kind() {
+	case reflect.Array, reflect.Slice:
+		rv := reflect.MakeSlice(seqv.Type(), 0, 0)
+		for i := 0; i < seqv.Len(); i++ {
+			var vvv reflect.Value
+			rvv := seqv.Index(i)
+			if kv.Kind() == reflect.String {
+				vvv = rvv
+				for _, elemName := range path {
+					vvv, err = evaluateSubElem(vvv, elemName)
+					if err != nil {
+						return nil, err
+					}
+				}
+			} else {
+				vv, _ := indirect(rvv)
+				if vv.Kind() == reflect.Map && kv.Type().AssignableTo(vv.Type().Key()) {
+					vvv = vv.MapIndex(kv)
+				}
+			}
+			if ok, err := checkCondition(vvv, mv, op); ok {
+				rv = reflect.Append(rv, rvv)
+			} else if err != nil {
+				return nil, err
+			}
+		}
+		return rv.Interface(), nil
+	default:
+		return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
+	}
+}
+
+// Apply, given a map, array, or slice, returns a new slice with the function fname applied over it.
+func Apply(seq interface{}, fname string, args ...interface{}) (interface{}, error) {
+	if seq == nil {
+		return make([]interface{}, 0), nil
+	}
+
+	if fname == "apply" {
+		return nil, errors.New("can't apply myself (no turtles allowed)")
+	}
+
+	seqv := reflect.ValueOf(seq)
+	seqv, isNil := indirect(seqv)
+	if isNil {
+		return nil, errors.New("can't iterate over a nil value")
+	}
+
+	fn, found := funcMap[fname]
+	if !found {
+		return nil, errors.New("can't find function " + fname)
+	}
+
+	fnv := reflect.ValueOf(fn)
+
+	switch seqv.Kind() {
+	case reflect.Array, reflect.Slice:
+		r := make([]interface{}, seqv.Len())
+		for i := 0; i < seqv.Len(); i++ {
+			vv := seqv.Index(i)
+
+			vvv, err := applyFnToThis(fnv, vv, args...)
+
+			if err != nil {
+				return nil, err
+			}
+
+			r[i] = vvv.Interface()
+		}
+
+		return r, nil
+	default:
+		return nil, errors.New("can't apply over " + reflect.ValueOf(seq).Type().String())
+	}
+}
+
+func applyFnToThis(fn, this reflect.Value, args ...interface{}) (reflect.Value, error) {
+	n := make([]reflect.Value, len(args))
+	for i, arg := range args {
+		if arg == "." {
+			n[i] = this
+		} else {
+			n[i] = reflect.ValueOf(arg)
+		}
+	}
+
+	res := fn.Call(n)
+
+	if len(res) == 1 || res[1].IsNil() {
+		return res[0], nil
+	} else {
+		return reflect.ValueOf(nil), res[1].Interface().(error)
+	}
+}
+
+func Delimit(seq, delimiter interface{}, last ...interface{}) (template.HTML, error) {
+	d, err := cast.ToStringE(delimiter)
+	if err != nil {
+		return "", err
+	}
+
+	var dLast *string
+	for _, l := range last {
+		dStr, err := cast.ToStringE(l)
+		if err != nil {
+			dLast = nil
+		}
+		dLast = &dStr
+		break
+	}
+
+	seqv := reflect.ValueOf(seq)
+	seqv, isNil := indirect(seqv)
+	if isNil {
+		return "", errors.New("can't iterate over a nil value")
+	}
+
+	var str string
+	switch seqv.Kind() {
+	case reflect.Map:
+		sortSeq, err := Sort(seq)
+		if err != nil {
+			return "", err
+		}
+		seqv = reflect.ValueOf(sortSeq)
+		fallthrough
+	case reflect.Array, reflect.Slice, reflect.String:
+		for i := 0; i < seqv.Len(); i++ {
+			val := seqv.Index(i).Interface()
+			valStr, err := cast.ToStringE(val)
+			if err != nil {
+				continue
+			}
+			switch {
+			case i == seqv.Len()-2 && dLast != nil:
+				str += valStr + *dLast
+			case i == seqv.Len()-1:
+				str += valStr
+			default:
+				str += valStr + d
+			}
+		}
+
+	default:
+		return "", errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
+	}
+
+	return template.HTML(str), nil
+}
+
+func Sort(seq interface{}, args ...interface{}) ([]interface{}, error) {
+	seqv := reflect.ValueOf(seq)
+	seqv, isNil := indirect(seqv)
+	if isNil {
+		return nil, errors.New("can't iterate over a nil value")
+	}
+
+	// Create a list of pairs that will be used to do the sort
+	p := pairList{SortAsc: true}
+	p.Pairs = make([]pair, seqv.Len())
+
+	for i, l := range args {
+		dStr, err := cast.ToStringE(l)
+		switch {
+		case i == 0 && err != nil:
+			p.SortByField = ""
+		case i == 0 && err == nil:
+			p.SortByField = dStr
+		case i == 1 && err == nil && dStr == "desc":
+			p.SortAsc = false
+		case i == 1:
+			p.SortAsc = true
+		}
+	}
+
+	var sorted []interface{}
+	switch seqv.Kind() {
+	case reflect.Array, reflect.Slice:
+		for i := 0; i < seqv.Len(); i++ {
+			p.Pairs[i].Key = reflect.ValueOf(i)
+			p.Pairs[i].Value = seqv.Index(i)
+		}
+		if p.SortByField == "" {
+			p.SortByField = "value"
+		}
+
+	case reflect.Map:
+		keys := seqv.MapKeys()
+		for i := 0; i < seqv.Len(); i++ {
+			p.Pairs[i].Key = keys[i]
+			p.Pairs[i].Value = seqv.MapIndex(keys[i])
+		}
+
+	default:
+		return nil, errors.New("can't sort " + reflect.ValueOf(seq).Type().String())
+	}
+	sorted = p.sort()
+	return sorted, nil
+}
+
+// Credit for pair sorting method goes to Andrew Gerrand
+// https://groups.google.com/forum/#!topic/golang-nuts/FT7cjmcL7gw
+// A data structure to hold a key/value pair.
+type pair struct {
+	Key   reflect.Value
+	Value reflect.Value
+}
+
+// A slice of pairs that implements sort.Interface to sort by Value.
+type pairList struct {
+	Pairs       []pair
+	SortByField string
+	SortAsc     bool
+}
+
+func (p pairList) Swap(i, j int) { p.Pairs[i], p.Pairs[j] = p.Pairs[j], p.Pairs[i] }
+func (p pairList) Len() int      { return len(p.Pairs) }
+func (p pairList) Less(i, j int) bool {
+	var truth bool
+	switch {
+	case p.SortByField == "value":
+		iVal := p.Pairs[i].Value
+		jVal := p.Pairs[j].Value
+		truth = Lt(iVal.Interface(), jVal.Interface())
+
+	case p.SortByField != "":
+		if p.Pairs[i].Value.FieldByName(p.SortByField).IsValid() {
+			iVal := p.Pairs[i].Value.FieldByName(p.SortByField)
+			jVal := p.Pairs[j].Value.FieldByName(p.SortByField)
+			truth = Lt(iVal.Interface(), jVal.Interface())
+		}
+	default:
+		iVal := p.Pairs[i].Key
+		jVal := p.Pairs[j].Key
+		truth = Lt(iVal.Interface(), jVal.Interface())
+	}
+	return truth
+}
+
+// sorts a pairList and returns a slice of sorted values
+func (p pairList) sort() []interface{} {
+	if p.SortAsc {
+		sort.Sort(p)
+	} else {
+		sort.Sort(sort.Reverse(p))
+	}
+	sorted := make([]interface{}, len(p.Pairs))
+	for i, v := range p.Pairs {
+		sorted[i] = v.Value.Interface()
+	}
+
+	return sorted
+}
+
+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, k interface{}) interface{} {
+	av, isNil := indirect(reflect.ValueOf(a))
+	if isNil {
+		return ""
+	}
+
+	var avv reflect.Value
+	switch av.Kind() {
+	case reflect.Array, reflect.Slice:
+		index, ok := k.(int)
+		if ok && av.Len() > index {
+			avv = av.Index(index)
+		}
+	case reflect.Map:
+		kv := reflect.ValueOf(k)
+		if kv.Type().AssignableTo(av.Type().Key()) {
+			avv = av.MapIndex(kv)
+		}
+	}
+
+	if avv.IsValid() {
+		switch avv.Kind() {
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			return avv.Int()
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+			return avv.Uint()
+		case reflect.Float32, reflect.Float64:
+			return avv.Float()
+		case reflect.String:
+			return avv.String()
+		}
+	}
+
+	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()
+	}
+
+	return template.HTML(helpers.Highlight(html.UnescapeString(str), lang))
+}
+
+var markdownTrimPrefix = []byte("<p>")
+var markdownTrimSuffix = []byte("</p>\n")
+
+func Markdownify(text string) template.HTML {
+	m := helpers.RenderBytes(&helpers.RenderingContext{Content: []byte(text), PageFmt: "markdown"})
+	m = bytes.TrimPrefix(m, markdownTrimPrefix)
+	m = bytes.TrimSuffix(m, markdownTrimSuffix)
+	return template.HTML(m)
+}
+
+func refPage(page interface{}, ref, methodName string) template.HTML {
+	value := reflect.ValueOf(page)
+
+	method := value.MethodByName(methodName)
+
+	if method.IsValid() && method.Type().NumIn() == 1 && method.Type().NumOut() == 2 {
+		result := method.Call([]reflect.Value{reflect.ValueOf(ref)})
+
+		url, err := result[0], result[1]
+
+		if !err.IsNil() {
+			jww.ERROR.Printf("%s", err.Interface())
+			return template.HTML(fmt.Sprintf("%s", err.Interface()))
+		}
+
+		if url.String() == "" {
+			jww.ERROR.Printf("ref %s could not be found\n", ref)
+			return template.HTML(ref)
+		}
+
+		return template.HTML(url.String())
+	}
+
+	jww.ERROR.Printf("Can only create references from Page and Node objects.")
+	return template.HTML(ref)
+}
+
+func Ref(page interface{}, ref string) template.HTML {
+	return refPage(page, ref, "Ref")
+}
+
+func RelRef(page interface{}, ref string) template.HTML {
+	return refPage(page, ref, "RelRef")
+}
+
+func Chomp(text interface{}) (string, error) {
+	s, err := cast.ToStringE(text)
+	if err != nil {
+		return "", err
+	}
+
+	return strings.TrimRight(s, "\r\n"), nil
+}
+
+// Trim leading/trailing characters defined by b from a
+func Trim(a interface{}, b string) (string, error) {
+	aStr, err := cast.ToStringE(a)
+	if err != nil {
+		return "", err
+	}
+	return strings.Trim(aStr, b), nil
+}
+
+// Replace all occurences of b with c in a
+func Replace(a, b, c interface{}) (string, error) {
+	aStr, err := cast.ToStringE(a)
+	if err != nil {
+		return "", err
+	}
+	bStr, err := cast.ToStringE(b)
+	if err != nil {
+		return "", err
+	}
+	cStr, err := cast.ToStringE(c)
+	if err != nil {
+		return "", err
+	}
+	return strings.Replace(aStr, bStr, cStr, -1), nil
+}
+
+// DateFormat converts the textual representation of the datetime string into
+// the other form or returns it of the time.Time value. These are formatted
+// with the layout string
+func DateFormat(layout string, v interface{}) (string, error) {
+	t, err := cast.ToTimeE(v)
+	if err != nil {
+		return "", err
+	}
+	return t.Format(layout), nil
+}
+
+func SafeHTML(text string) template.HTML {
+	return template.HTML(text)
+}
+
+// "safeHTMLAttr" is currently disabled, pending further discussion
+// on its use case.  2015-01-19
+func SafeHTMLAttr(text string) template.HTMLAttr {
+	return template.HTMLAttr(text)
+}
+
+func SafeCSS(text string) template.CSS {
+	return template.CSS(text)
+}
+
+func SafeURL(text string) template.URL {
+	return template.URL(text)
+}
+
+func doArithmetic(a, b interface{}, op rune) (interface{}, error) {
+	av := reflect.ValueOf(a)
+	bv := reflect.ValueOf(b)
+	var ai, bi int64
+	var af, bf float64
+	var au, bu uint64
+	switch av.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		ai = av.Int()
+		switch bv.Kind() {
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			bi = bv.Int()
+		case reflect.Float32, reflect.Float64:
+			af = float64(ai) // may overflow
+			ai = 0
+			bf = bv.Float()
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+			bu = bv.Uint()
+			if ai >= 0 {
+				au = uint64(ai)
+				ai = 0
+			} else {
+				bi = int64(bu) // may overflow
+				bu = 0
+			}
+		default:
+			return nil, errors.New("Can't apply the operator to the values")
+		}
+	case reflect.Float32, reflect.Float64:
+		af = av.Float()
+		switch bv.Kind() {
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			bf = float64(bv.Int()) // may overflow
+		case reflect.Float32, reflect.Float64:
+			bf = bv.Float()
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+			bf = float64(bv.Uint()) // may overflow
+		default:
+			return nil, errors.New("Can't apply the operator to the values")
+		}
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		au = av.Uint()
+		switch bv.Kind() {
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			bi = bv.Int()
+			if bi >= 0 {
+				bu = uint64(bi)
+				bi = 0
+			} else {
+				ai = int64(au) // may overflow
+				au = 0
+			}
+		case reflect.Float32, reflect.Float64:
+			af = float64(au) // may overflow
+			au = 0
+			bf = bv.Float()
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+			bu = bv.Uint()
+		default:
+			return nil, errors.New("Can't apply the operator to the values")
+		}
+	case reflect.String:
+		as := av.String()
+		if bv.Kind() == reflect.String && op == '+' {
+			bs := bv.String()
+			return as + bs, nil
+		} else {
+			return nil, errors.New("Can't apply the operator to the values")
+		}
+	default:
+		return nil, errors.New("Can't apply the operator to the values")
+	}
+
+	switch op {
+	case '+':
+		if ai != 0 || bi != 0 {
+			return ai + bi, nil
+		} else if af != 0 || bf != 0 {
+			return af + bf, nil
+		} else if au != 0 || bu != 0 {
+			return au + bu, nil
+		} else {
+			return 0, nil
+		}
+	case '-':
+		if ai != 0 || bi != 0 {
+			return ai - bi, nil
+		} else if af != 0 || bf != 0 {
+			return af - bf, nil
+		} else if au != 0 || bu != 0 {
+			return au - bu, nil
+		} else {
+			return 0, nil
+		}
+	case '*':
+		if ai != 0 || bi != 0 {
+			return ai * bi, nil
+		} else if af != 0 || bf != 0 {
+			return af * bf, nil
+		} else if au != 0 || bu != 0 {
+			return au * bu, nil
+		} else {
+			return 0, nil
+		}
+	case '/':
+		if bi != 0 {
+			return ai / bi, nil
+		} else if bf != 0 {
+			return af / bf, nil
+		} else if bu != 0 {
+			return au / bu, nil
+		} else {
+			return nil, errors.New("Can't divide the value by 0")
+		}
+	default:
+		return nil, errors.New("There is no such an operation")
+	}
+}
+
+func Mod(a, b interface{}) (int64, error) {
+	av := reflect.ValueOf(a)
+	bv := reflect.ValueOf(b)
+	var ai, bi int64
+
+	switch av.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		ai = av.Int()
+	default:
+		return 0, errors.New("Modulo operator can't be used with non integer value")
+	}
+
+	switch bv.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		bi = bv.Int()
+	default:
+		return 0, errors.New("Modulo operator can't be used with non integer value")
+	}
+
+	if bi == 0 {
+		return 0, errors.New("The number can't be divided by zero at modulo operation")
+	}
+
+	return ai % bi, nil
+}
+
+func ModBool(a, b interface{}) (bool, error) {
+	res, err := Mod(a, b)
+	if err != nil {
+		return false, err
+	}
+	return res == int64(0), nil
+}
+
+func init() {
+	funcMap = template.FuncMap{
+		"urlize":      helpers.URLize,
+		"sanitizeURL": helpers.SanitizeURL,
+		"sanitizeurl": helpers.SanitizeURL,
+		"eq":          Eq,
+		"ne":          Ne,
+		"gt":          Gt,
+		"ge":          Ge,
+		"lt":          Lt,
+		"le":          Le,
+		"in":          In,
+		"slicestr":    Slicestr,
+		"substr":      Substr,
+		"split":       Split,
+		"intersect":   Intersect,
+		"isSet":       IsSet,
+		"isset":       IsSet,
+		"echoParam":   ReturnWhenSet,
+		"safeHTML":    SafeHTML,
+		"safeCSS":     SafeCSS,
+		"safeURL":     SafeURL,
+		"markdownify": Markdownify,
+		"first":       First,
+		"where":       Where,
+		"delimit":     Delimit,
+		"sort":        Sort,
+		"highlight":   Highlight,
+		"add":         func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '+') },
+		"sub":         func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '-') },
+		"div":         func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '/') },
+		"mod":         Mod,
+		"mul":         func(a, b interface{}) (interface{}, error) { return doArithmetic(a, b, '*') },
+		"modBool":     ModBool,
+		"lower":       func(a string) string { return strings.ToLower(a) },
+		"upper":       func(a string) string { return strings.ToUpper(a) },
+		"title":       func(a string) string { return strings.Title(a) },
+		"partial":     Partial,
+		"ref":         Ref,
+		"relref":      RelRef,
+		"apply":       Apply,
+		"chomp":       Chomp,
+		"replace":     Replace,
+		"trim":        Trim,
+		"dateFormat":  DateFormat,
+		"getJSON":     GetJSON,
+		"getCSV":      GetCSV,
+		"seq":         helpers.Seq,
+		"getenv":      func(varName string) string { return os.Getenv(varName) },
+
+		// "getJson" is deprecated. Will be removed in 0.15.
+		"getJson": func(urlParts ...string) interface{} {
+			helpers.Deprecated("Template", "getJson", "getJSON")
+			return GetJSON(urlParts...)
+		},
+		// "getJson" is deprecated. Will be removed in 0.15.
+		"getCsv": func(sep string, urlParts ...string) [][]string {
+			helpers.Deprecated("Template", "getCsv", "getCSV")
+			return GetCSV(sep, urlParts...)
+		},
+		// "safeHtml" is deprecated. Will be removed in 0.15.
+		"safeHtml": func(text string) template.HTML {
+			helpers.Deprecated("Template", "safeHtml", "safeHTML")
+			return SafeHTML(text)
+		},
+		// "safeCss" is deprecated. Will be removed in 0.15.
+		"safeCss": func(text string) template.CSS {
+			helpers.Deprecated("Template", "safeCss", "safeCSS")
+			return SafeCSS(text)
+		},
+		// "safeUrl" is deprecated. Will be removed in 0.15.
+		"safeUrl": func(text string) template.URL {
+			helpers.Deprecated("Template", "safeUrl", "safeURL")
+			return SafeURL(text)
+		},
+	}
+
+}
--- /dev/null
+++ b/tpl/template_funcs_test.go
@@ -1,0 +1,1222 @@
+package tpl
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"github.com/stretchr/testify/assert"
+	"html/template"
+	"path"
+	"reflect"
+	"runtime"
+	"testing"
+	"time"
+)
+
+type tstNoStringer struct {
+}
+
+type tstCompareType int
+
+const (
+	tstEq tstCompareType = iota
+	tstNe
+	tstGt
+	tstGe
+	tstLt
+	tstLe
+)
+
+func tstIsEq(tp tstCompareType) bool {
+	return tp == tstEq || tp == tstGe || tp == tstLe
+}
+
+func tstIsGt(tp tstCompareType) bool {
+	return tp == tstGt || tp == tstGe
+}
+
+func tstIsLt(tp tstCompareType) bool {
+	return tp == tstLt || tp == tstLe
+}
+
+func TestCompare(t *testing.T) {
+	for _, this := range []struct {
+		tstCompareType
+		funcUnderTest func(a, b interface{}) bool
+	}{
+		{tstGt, Gt},
+		{tstLt, Lt},
+		{tstGe, Ge},
+		{tstLe, Le},
+		{tstEq, Eq},
+		{tstNe, Ne},
+	} {
+		doTestCompare(t, this.tstCompareType, this.funcUnderTest)
+	}
+
+}
+
+func doTestCompare(t *testing.T, tp tstCompareType, funcUnderTest func(a, b interface{}) bool) {
+	for i, this := range []struct {
+		left            interface{}
+		right           interface{}
+		expectIndicator int
+	}{
+		{5, 8, -1},
+		{8, 5, 1},
+		{5, 5, 0},
+		{int(5), int64(5), 0},
+		{int32(5), int(5), 0},
+		{int16(4), int(5), -1},
+		{uint(15), uint64(15), 0},
+		{-2, 1, -1},
+		{2, -5, 1},
+		{0.0, 1.23, -1},
+		{1.1, 1.1, 0},
+		{float32(1.0), float64(1.0), 0},
+		{1.23, 0.0, 1},
+		{"5", "5", 0},
+		{"8", "5", 1},
+		{"5", "0001", 1},
+		{[]int{100, 99}, []int{1, 2, 3, 4}, -1},
+	} {
+		result := funcUnderTest(this.left, this.right)
+		success := false
+
+		if this.expectIndicator == 0 {
+			if tstIsEq(tp) {
+				success = result
+			} else {
+				success = !result
+			}
+		}
+
+		if this.expectIndicator < 0 {
+			success = result && (tstIsLt(tp) || tp == tstNe)
+			success = success || (!result && !tstIsLt(tp))
+		}
+
+		if this.expectIndicator > 0 {
+			success = result && (tstIsGt(tp) || tp == tstNe)
+			success = success || (!result && (!tstIsGt(tp) || tp != tstNe))
+		}
+
+		if !success {
+			t.Errorf("[%d][%s] %v compared to %v: %t", i, path.Base(runtime.FuncForPC(reflect.ValueOf(funcUnderTest).Pointer()).Name()), this.left, this.right, result)
+		}
+	}
+}
+
+func TestArethmic(t *testing.T) {
+	for i, this := range []struct {
+		a      interface{}
+		b      interface{}
+		op     rune
+		expect interface{}
+	}{
+		{1, 2, '+', int64(3)},
+		{1, 2, '-', int64(-1)},
+		{2, 2, '*', int64(4)},
+		{4, 2, '/', int64(2)},
+		{uint8(1), uint8(3), '+', uint64(4)},
+		{uint8(3), uint8(2), '-', uint64(1)},
+		{uint8(2), uint8(2), '*', uint64(4)},
+		{uint16(4), uint8(2), '/', uint64(2)},
+		{4, 2, '¤', false},
+		{4, 0, '/', false},
+	} {
+		// TODO(bep): Take precision into account.
+		result, err := doArithmetic(this.a, this.b, this.op)
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] doArethmic didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if !reflect.DeepEqual(result, this.expect) {
+				t.Errorf("[%d] doArethmic got %v (%T) but expected %v (%T)", i, result, result, this.expect, this.expect)
+			}
+		}
+	}
+}
+
+func TestMod(t *testing.T) {
+	for i, this := range []struct {
+		a      interface{}
+		b      interface{}
+		expect interface{}
+	}{
+		{3, 2, int64(1)},
+		{3, 1, int64(0)},
+		{3, 0, false},
+		{0, 3, int64(0)},
+		{3.1, 2, false},
+		{3, 2.1, false},
+		{3.1, 2.1, false},
+		{int8(3), int8(2), int64(1)},
+		{int16(3), int16(2), int64(1)},
+		{int32(3), int32(2), int64(1)},
+		{int64(3), int64(2), int64(1)},
+	} {
+		result, err := Mod(this.a, this.b)
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] modulo didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if !reflect.DeepEqual(result, this.expect) {
+				t.Errorf("[%d] modulo got %v but expected %v", i, result, this.expect)
+			}
+		}
+	}
+}
+
+func TestModBool(t *testing.T) {
+	for i, this := range []struct {
+		a      interface{}
+		b      interface{}
+		expect interface{}
+	}{
+		{3, 3, true},
+		{3, 2, false},
+		{3, 1, true},
+		{3, 0, nil},
+		{0, 3, true},
+		{3.1, 2, nil},
+		{3, 2.1, nil},
+		{3.1, 2.1, nil},
+		{int8(3), int8(3), true},
+		{int8(3), int8(2), false},
+		{int16(3), int16(3), true},
+		{int16(3), int16(2), false},
+		{int32(3), int32(3), true},
+		{int32(3), int32(2), false},
+		{int64(3), int64(3), true},
+		{int64(3), int64(2), false},
+	} {
+		result, err := ModBool(this.a, this.b)
+		if this.expect == nil {
+			if err == nil {
+				t.Errorf("[%d] modulo didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if !reflect.DeepEqual(result, this.expect) {
+				t.Errorf("[%d] modulo got %v but expected %v", i, result, this.expect)
+			}
+		}
+	}
+}
+
+func TestFirst(t *testing.T) {
+	for i, this := range []struct {
+		count    interface{}
+		sequence interface{}
+		expect   interface{}
+	}{
+		{int(2), []string{"a", "b", "c"}, []string{"a", "b"}},
+		{int32(3), []string{"a", "b"}, []string{"a", "b"}},
+		{int64(2), []int{100, 200, 300}, []int{100, 200}},
+		{100, []int{100, 200}, []int{100, 200}},
+		{"1", []int{100, 200, 300}, []int{100}},
+		{int64(-1), []int{100, 200, 300}, false},
+		{"noint", []int{100, 200, 300}, false},
+		{1, nil, false},
+		{nil, []int{100}, false},
+		{1, t, false},
+	} {
+		results, err := First(this.count, this.sequence)
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] First didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if !reflect.DeepEqual(results, this.expect) {
+				t.Errorf("[%d] First %d items, got %v but expected %v", i, this.count, results, this.expect)
+			}
+		}
+	}
+}
+
+func TestIn(t *testing.T) {
+	for i, this := range []struct {
+		v1     interface{}
+		v2     interface{}
+		expect bool
+	}{
+		{[]string{"a", "b", "c"}, "b", true},
+		{[]string{"a", "b", "c"}, "d", false},
+		{[]string{"a", "12", "c"}, 12, false},
+		{[]int{1, 2, 4}, 2, true},
+		{[]int{1, 2, 4}, 3, false},
+		{[]float64{1.23, 2.45, 4.67}, 1.23, true},
+		{[]float64{1.234567, 2.45, 4.67}, 1.234568, false},
+		{"this substring should be found", "substring", true},
+		{"this substring should not be found", "subseastring", false},
+	} {
+		result := In(this.v1, this.v2)
+
+		if result != this.expect {
+			t.Errorf("[%d] Got %v but expected %v", i, result, this.expect)
+		}
+	}
+}
+
+func TestSlicestr(t *testing.T) {
+	for i, this := range []struct {
+		v1     interface{}
+		v2     []int
+		expect interface{}
+	}{
+		{"abc", []int{1, 2}, "b"},
+		{"abc", []int{1, 3}, "bc"},
+		{"abc", []int{0, 1}, "a"},
+		{"abcdef", []int{}, "abcdef"},
+		{"abcdef", []int{0, 6}, "abcdef"},
+		{"abcdef", []int{0, 2}, "ab"},
+		{"abcdef", []int{2}, "cdef"},
+		{123, []int{1, 3}, "23"},
+		{123, []int{1, 2, 3}, false},
+		{tstNoStringer{}, []int{0, 1}, false},
+	} {
+		result, err := Slicestr(this.v1, this.v2...)
+
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] Slice didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if !reflect.DeepEqual(result, this.expect) {
+				t.Errorf("[%d] Got %s but expected %s", i, result, this.expect)
+			}
+		}
+	}
+}
+
+func TestSubstr(t *testing.T) {
+	for i, this := range []struct {
+		v1     interface{}
+		v2     int
+		v3     int
+		expect interface{}
+	}{
+		{"abc", 1, 2, "bc"},
+		{"abc", 0, 1, "a"},
+		{"abcdef", -1, 2, "ef"},
+		{"abcdef", -3, 3, "bcd"},
+		{"abcdef", 0, -1, "abcde"},
+		{"abcdef", 2, -1, "cde"},
+		{"abcdef", 4, -4, false},
+		{"abcdef", 7, 1, false},
+		{"abcdef", 1, 100, "bcdef"},
+		{"abcdef", -100, 3, "abc"},
+		{"abcdef", -3, -1, "de"},
+		{123, 1, 3, "23"},
+		{1.2e3, 0, 4, "1200"},
+		{tstNoStringer{}, 0, 1, false},
+	} {
+		result, err := Substr(this.v1, this.v2, this.v3)
+
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] Substr didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if !reflect.DeepEqual(result, this.expect) {
+				t.Errorf("[%d] Got %s but expected %s", i, result, this.expect)
+			}
+		}
+	}
+}
+
+func TestSplit(t *testing.T) {
+	for i, this := range []struct {
+		v1     interface{}
+		v2     string
+		expect interface{}
+	}{
+		{"a, b", ", ", []string{"a", "b"}},
+		{"a & b & c", " & ", []string{"a", "b", "c"}},
+		{"http://exmaple.com", "http://", []string{"", "exmaple.com"}},
+		{123, "2", []string{"1", "3"}},
+		{tstNoStringer{}, ",", false},
+	} {
+		result, err := Split(this.v1, this.v2)
+
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] Split didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if !reflect.DeepEqual(result, this.expect) {
+				t.Errorf("[%d] Got %s but expected %s", i, result, this.expect)
+			}
+		}
+	}
+
+}
+
+func TestIntersect(t *testing.T) {
+	for i, this := range []struct {
+		sequence1 interface{}
+		sequence2 interface{}
+		expect    interface{}
+	}{
+		{[]string{"a", "b", "c"}, []string{"a", "b"}, []string{"a", "b"}},
+		{[]string{"a", "b"}, []string{"a", "b", "c"}, []string{"a", "b"}},
+		{[]string{"a", "b", "c"}, []string{"d", "e"}, []string{}},
+		{[]string{}, []string{}, []string{}},
+		{[]string{"a", "b"}, nil, make([]interface{}, 0)},
+		{nil, []string{"a", "b"}, make([]interface{}, 0)},
+		{nil, nil, make([]interface{}, 0)},
+		{[]string{"1", "2"}, []int{1, 2}, []string{}},
+		{[]int{1, 2}, []string{"1", "2"}, []int{}},
+		{[]int{1, 2, 4}, []int{2, 4}, []int{2, 4}},
+		{[]int{2, 4}, []int{1, 2, 4}, []int{2, 4}},
+		{[]int{1, 2, 4}, []int{3, 6}, []int{}},
+		{[]float64{2.2, 4.4}, []float64{1.1, 2.2, 4.4}, []float64{2.2, 4.4}},
+	} {
+		results, err := Intersect(this.sequence1, this.sequence2)
+		if err != nil {
+			t.Errorf("[%d] failed: %s", i, err)
+			continue
+		}
+		if !reflect.DeepEqual(results, this.expect) {
+			t.Errorf("[%d] Got %v but expected %v", i, results, this.expect)
+		}
+	}
+
+	_, err1 := Intersect("not an array or slice", []string{"a"})
+
+	if err1 == nil {
+		t.Error("Excpected error for non array as first arg")
+	}
+
+	_, err2 := Intersect([]string{"a"}, "not an array or slice")
+
+	if err2 == nil {
+		t.Error("Excpected error for non array as second arg")
+	}
+}
+
+func TestIsSet(t *testing.T) {
+	aSlice := []interface{}{1, 2, 3, 5}
+	aMap := map[string]interface{}{"a": 1, "b": 2}
+
+	assert.True(t, IsSet(aSlice, 2))
+	assert.True(t, IsSet(aMap, "b"))
+	assert.False(t, IsSet(aSlice, 22))
+	assert.False(t, IsSet(aMap, "bc"))
+}
+
+func (x *TstX) TstRp() string {
+	return "r" + x.A
+}
+
+func (x TstX) TstRv() string {
+	return "r" + x.B
+}
+
+func (x TstX) unexportedMethod() string {
+	return x.unexported
+}
+
+func (x TstX) MethodWithArg(s string) string {
+	return s
+}
+
+func (x TstX) MethodReturnNothing() {}
+
+func (x TstX) MethodReturnErrorOnly() error {
+	return errors.New("something error occured")
+}
+
+func (x TstX) MethodReturnTwoValues() (string, string) {
+	return "foo", "bar"
+}
+
+func (x TstX) MethodReturnValueWithError() (string, error) {
+	return "", errors.New("something error occured")
+}
+
+func (x TstX) String() string {
+	return fmt.Sprintf("A: %s, B: %s", x.A, x.B)
+}
+
+type TstX struct {
+	A, B       string
+	unexported string
+}
+
+func TestEvaluateSubElem(t *testing.T) {
+	tstx := TstX{A: "foo", B: "bar"}
+	var inner struct {
+		S fmt.Stringer
+	}
+	inner.S = tstx
+	interfaceValue := reflect.ValueOf(&inner).Elem().Field(0)
+
+	for i, this := range []struct {
+		value  reflect.Value
+		key    string
+		expect interface{}
+	}{
+		{reflect.ValueOf(tstx), "A", "foo"},
+		{reflect.ValueOf(&tstx), "TstRp", "rfoo"},
+		{reflect.ValueOf(tstx), "TstRv", "rbar"},
+		//{reflect.ValueOf(map[int]string{1: "foo", 2: "bar"}), 1, "foo"},
+		{reflect.ValueOf(map[string]string{"key1": "foo", "key2": "bar"}), "key1", "foo"},
+		{interfaceValue, "String", "A: foo, B: bar"},
+		{reflect.Value{}, "foo", false},
+		//{reflect.ValueOf(map[int]string{1: "foo", 2: "bar"}), 1.2, false},
+		{reflect.ValueOf(tstx), "unexported", false},
+		{reflect.ValueOf(tstx), "unexportedMethod", false},
+		{reflect.ValueOf(tstx), "MethodWithArg", false},
+		{reflect.ValueOf(tstx), "MethodReturnNothing", false},
+		{reflect.ValueOf(tstx), "MethodReturnErrorOnly", false},
+		{reflect.ValueOf(tstx), "MethodReturnTwoValues", false},
+		{reflect.ValueOf(tstx), "MethodReturnValueWithError", false},
+		{reflect.ValueOf((*TstX)(nil)), "A", false},
+		{reflect.ValueOf(tstx), "C", false},
+		{reflect.ValueOf(map[int]string{1: "foo", 2: "bar"}), "1", false},
+		{reflect.ValueOf([]string{"foo", "bar"}), "1", false},
+	} {
+		result, err := evaluateSubElem(this.value, this.key)
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] evaluateSubElem didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if result.Kind() != reflect.String || result.String() != this.expect {
+				t.Errorf("[%d] evaluateSubElem with %v got %v but expected %v", i, this.key, result, this.expect)
+			}
+		}
+	}
+}
+
+func TestCheckCondition(t *testing.T) {
+	type expect struct {
+		result  bool
+		isError bool
+	}
+
+	for i, this := range []struct {
+		value reflect.Value
+		match reflect.Value
+		op    string
+		expect
+	}{
+		{reflect.ValueOf(123), reflect.ValueOf(123), "", expect{true, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf("foo"), "", expect{true, false}},
+		{reflect.ValueOf(123), reflect.ValueOf(456), "!=", expect{true, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf("bar"), "!=", expect{true, false}},
+		{reflect.ValueOf(456), reflect.ValueOf(123), ">=", expect{true, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf("bar"), ">=", expect{true, false}},
+		{reflect.ValueOf(456), reflect.ValueOf(123), ">", expect{true, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf("bar"), ">", expect{true, false}},
+		{reflect.ValueOf(123), reflect.ValueOf(456), "<=", expect{true, false}},
+		{reflect.ValueOf("bar"), reflect.ValueOf("foo"), "<=", expect{true, false}},
+		{reflect.ValueOf(123), reflect.ValueOf(456), "<", expect{true, false}},
+		{reflect.ValueOf("bar"), reflect.ValueOf("foo"), "<", expect{true, false}},
+		{reflect.ValueOf(123), reflect.ValueOf([]int{123, 45, 678}), "in", expect{true, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf([]string{"foo", "bar", "baz"}), "in", expect{true, false}},
+		{reflect.ValueOf(123), reflect.ValueOf([]int{45, 678}), "not in", expect{true, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf([]string{"bar", "baz"}), "not in", expect{true, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf("bar-foo-baz"), "in", expect{true, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf("bar--baz"), "not in", expect{true, false}},
+		{reflect.Value{}, reflect.ValueOf("foo"), "", expect{false, false}},
+		{reflect.ValueOf("foo"), reflect.Value{}, "", expect{false, false}},
+		{reflect.ValueOf((*TstX)(nil)), reflect.ValueOf("foo"), "", expect{false, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf((*TstX)(nil)), "", expect{false, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf(map[int]string{}), "", expect{false, false}},
+		{reflect.ValueOf("foo"), reflect.ValueOf([]int{1, 2}), "", expect{false, false}},
+		{reflect.ValueOf(123), reflect.ValueOf([]int{}), "in", expect{false, false}},
+		{reflect.ValueOf(123), reflect.ValueOf(123), "op", expect{false, true}},
+	} {
+		result, err := checkCondition(this.value, this.match, this.op)
+		if this.expect.isError {
+			if err == nil {
+				t.Errorf("[%d] checkCondition didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if result != this.expect.result {
+				t.Errorf("[%d] check condition %v %s %v, got %v but expected %v", i, this.value, this.op, this.match, result, this.expect.result)
+			}
+		}
+	}
+}
+
+func TestWhere(t *testing.T) {
+	// TODO(spf): Put these page tests back in
+	//page1 := &Page{contentType: "v", Source: Source{File: *source.NewFile("/x/y/z/source.md")}}
+	//page2 := &Page{contentType: "w", Source: Source{File: *source.NewFile("/y/z/a/source.md")}}
+
+	type Mid struct {
+		Tst TstX
+	}
+
+	for i, this := range []struct {
+		sequence interface{}
+		key      interface{}
+		op       string
+		match    interface{}
+		expect   interface{}
+	}{
+		{
+			sequence: []map[int]string{
+				{1: "a", 2: "m"}, {1: "c", 2: "d"}, {1: "e", 3: "m"},
+			},
+			key: 2, match: "m",
+			expect: []map[int]string{
+				{1: "a", 2: "m"},
+			},
+		},
+		{
+			sequence: []map[string]int{
+				{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4},
+			},
+			key: "b", match: 4,
+			expect: []map[string]int{
+				{"a": 3, "b": 4},
+			},
+		},
+		{
+			sequence: []TstX{
+				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
+			},
+			key: "B", match: "f",
+			expect: []TstX{
+				{A: "e", B: "f"},
+			},
+		},
+		{
+			sequence: []*map[int]string{
+				{1: "a", 2: "m"}, {1: "c", 2: "d"}, {1: "e", 3: "m"},
+			},
+			key: 2, match: "m",
+			expect: []*map[int]string{
+				{1: "a", 2: "m"},
+			},
+		},
+		{
+			sequence: []*TstX{
+				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
+			},
+			key: "B", match: "f",
+			expect: []*TstX{
+				{A: "e", B: "f"},
+			},
+		},
+		{
+			sequence: []*TstX{
+				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "c"},
+			},
+			key: "TstRp", match: "rc",
+			expect: []*TstX{
+				{A: "c", B: "d"},
+			},
+		},
+		{
+			sequence: []TstX{
+				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "c"},
+			},
+			key: "TstRv", match: "rc",
+			expect: []TstX{
+				{A: "e", B: "c"},
+			},
+		},
+		{
+			sequence: []map[string]TstX{
+				{"foo": TstX{A: "a", B: "b"}}, {"foo": TstX{A: "c", B: "d"}}, {"foo": TstX{A: "e", B: "f"}},
+			},
+			key: "foo.B", match: "d",
+			expect: []map[string]TstX{
+				{"foo": TstX{A: "c", B: "d"}},
+			},
+		},
+		{
+			sequence: []map[string]TstX{
+				{"foo": TstX{A: "a", B: "b"}}, {"foo": TstX{A: "c", B: "d"}}, {"foo": TstX{A: "e", B: "f"}},
+			},
+			key: ".foo.B", match: "d",
+			expect: []map[string]TstX{
+				{"foo": TstX{A: "c", B: "d"}},
+			},
+		},
+		{
+			sequence: []map[string]TstX{
+				{"foo": TstX{A: "a", B: "b"}}, {"foo": TstX{A: "c", B: "d"}}, {"foo": TstX{A: "e", B: "f"}},
+			},
+			key: "foo.TstRv", match: "rd",
+			expect: []map[string]TstX{
+				{"foo": TstX{A: "c", B: "d"}},
+			},
+		},
+		{
+			sequence: []map[string]*TstX{
+				{"foo": &TstX{A: "a", B: "b"}}, {"foo": &TstX{A: "c", B: "d"}}, {"foo": &TstX{A: "e", B: "f"}},
+			},
+			key: "foo.TstRp", match: "rc",
+			expect: []map[string]*TstX{
+				{"foo": &TstX{A: "c", B: "d"}},
+			},
+		},
+		{
+			sequence: []map[string]Mid{
+				{"foo": Mid{Tst: TstX{A: "a", B: "b"}}}, {"foo": Mid{Tst: TstX{A: "c", B: "d"}}}, {"foo": Mid{Tst: TstX{A: "e", B: "f"}}},
+			},
+			key: "foo.Tst.B", match: "d",
+			expect: []map[string]Mid{
+				{"foo": Mid{Tst: TstX{A: "c", B: "d"}}},
+			},
+		},
+		{
+			sequence: []map[string]Mid{
+				{"foo": Mid{Tst: TstX{A: "a", B: "b"}}}, {"foo": Mid{Tst: TstX{A: "c", B: "d"}}}, {"foo": Mid{Tst: TstX{A: "e", B: "f"}}},
+			},
+			key: "foo.Tst.TstRv", match: "rd",
+			expect: []map[string]Mid{
+				{"foo": Mid{Tst: TstX{A: "c", B: "d"}}},
+			},
+		},
+		{
+			sequence: []map[string]*Mid{
+				{"foo": &Mid{Tst: TstX{A: "a", B: "b"}}}, {"foo": &Mid{Tst: TstX{A: "c", B: "d"}}}, {"foo": &Mid{Tst: TstX{A: "e", B: "f"}}},
+			},
+			key: "foo.Tst.TstRp", match: "rc",
+			expect: []map[string]*Mid{
+				{"foo": &Mid{Tst: TstX{A: "c", B: "d"}}},
+			},
+		},
+		{
+			sequence: []map[string]int{
+				{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6},
+			},
+			key: "b", op: ">", match: 3,
+			expect: []map[string]int{
+				{"a": 3, "b": 4}, {"a": 5, "b": 6},
+			},
+		},
+		{
+			sequence: []TstX{
+				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
+			},
+			key: "B", op: "!=", match: "f",
+			expect: []TstX{
+				{A: "a", B: "b"}, {A: "c", B: "d"},
+			},
+		},
+		{
+			sequence: []map[string]int{
+				{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6},
+			},
+			key: "b", op: "in", match: []int{3, 4, 5},
+			expect: []map[string]int{
+				{"a": 3, "b": 4},
+			},
+		},
+		{
+			sequence: []TstX{
+				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
+			},
+			key: "B", op: "not in", match: []string{"c", "d", "e"},
+			expect: []TstX{
+				{A: "a", B: "b"}, {A: "e", B: "f"},
+			},
+		},
+		{sequence: (*[]TstX)(nil), key: "A", match: "a", expect: false},
+		{sequence: TstX{A: "a", B: "b"}, key: "A", match: "a", expect: false},
+		{sequence: []map[string]*TstX{{"foo": nil}}, key: "foo.B", match: "d", expect: false},
+		{
+			sequence: []TstX{
+				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
+			},
+			key: "B", op: "op", match: "f",
+			expect: false,
+		},
+		//{[]*Page{page1, page2}, "Type", "v", []*Page{page1}},
+		//{[]*Page{page1, page2}, "Section", "y", []*Page{page2}},
+	} {
+		var results interface{}
+		var err error
+		if len(this.op) > 0 {
+			results, err = Where(this.sequence, this.key, this.op, this.match)
+		} else {
+			results, err = Where(this.sequence, this.key, this.match)
+		}
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] Where didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if !reflect.DeepEqual(results, this.expect) {
+				t.Errorf("[%d] Where clause matching %v with %v, got %v but expected %v", i, this.key, this.match, results, this.expect)
+			}
+		}
+	}
+
+	var err error
+	_, err = Where(map[string]int{"a": 1, "b": 2}, "a", []byte("="), 1)
+	if err == nil {
+		t.Errorf("Where called with none string op value didn't return an expected error")
+	}
+
+	_, err = Where(map[string]int{"a": 1, "b": 2}, "a", []byte("="), 1, 2)
+	if err == nil {
+		t.Errorf("Where called with more than two variable arguments didn't return an expected error")
+	}
+
+	_, err = Where(map[string]int{"a": 1, "b": 2}, "a")
+	if err == nil {
+		t.Errorf("Where called with no variable arguments didn't return an expected error")
+	}
+}
+
+func TestDelimit(t *testing.T) {
+	for i, this := range []struct {
+		sequence  interface{}
+		delimiter interface{}
+		last      interface{}
+		expect    template.HTML
+	}{
+		{[]string{"class1", "class2", "class3"}, " ", nil, "class1 class2 class3"},
+		{[]int{1, 2, 3, 4, 5}, ",", nil, "1,2,3,4,5"},
+		{[]int{1, 2, 3, 4, 5}, ", ", nil, "1, 2, 3, 4, 5"},
+		{[]string{"class1", "class2", "class3"}, " ", " and ", "class1 class2 and class3"},
+		{[]int{1, 2, 3, 4, 5}, ",", ",", "1,2,3,4,5"},
+		{[]int{1, 2, 3, 4, 5}, ", ", ", and ", "1, 2, 3, 4, and 5"},
+		// test maps with and without sorting required
+		{map[string]int{"1": 10, "2": 20, "3": 30, "4": 40, "5": 50}, "--", nil, "10--20--30--40--50"},
+		{map[string]int{"3": 10, "2": 20, "1": 30, "4": 40, "5": 50}, "--", nil, "30--20--10--40--50"},
+		{map[string]string{"1": "10", "2": "20", "3": "30", "4": "40", "5": "50"}, "--", nil, "10--20--30--40--50"},
+		{map[string]string{"3": "10", "2": "20", "1": "30", "4": "40", "5": "50"}, "--", nil, "30--20--10--40--50"},
+		{map[string]string{"one": "10", "two": "20", "three": "30", "four": "40", "five": "50"}, "--", nil, "50--40--10--30--20"},
+		{map[int]string{1: "10", 2: "20", 3: "30", 4: "40", 5: "50"}, "--", nil, "10--20--30--40--50"},
+		{map[int]string{3: "10", 2: "20", 1: "30", 4: "40", 5: "50"}, "--", nil, "30--20--10--40--50"},
+		{map[float64]string{3.3: "10", 2.3: "20", 1.3: "30", 4.3: "40", 5.3: "50"}, "--", nil, "30--20--10--40--50"},
+		// test maps with a last delimiter
+		{map[string]int{"1": 10, "2": 20, "3": 30, "4": 40, "5": 50}, "--", "--and--", "10--20--30--40--and--50"},
+		{map[string]int{"3": 10, "2": 20, "1": 30, "4": 40, "5": 50}, "--", "--and--", "30--20--10--40--and--50"},
+		{map[string]string{"1": "10", "2": "20", "3": "30", "4": "40", "5": "50"}, "--", "--and--", "10--20--30--40--and--50"},
+		{map[string]string{"3": "10", "2": "20", "1": "30", "4": "40", "5": "50"}, "--", "--and--", "30--20--10--40--and--50"},
+		{map[string]string{"one": "10", "two": "20", "three": "30", "four": "40", "five": "50"}, "--", "--and--", "50--40--10--30--and--20"},
+		{map[int]string{1: "10", 2: "20", 3: "30", 4: "40", 5: "50"}, "--", "--and--", "10--20--30--40--and--50"},
+		{map[int]string{3: "10", 2: "20", 1: "30", 4: "40", 5: "50"}, "--", "--and--", "30--20--10--40--and--50"},
+		{map[float64]string{3.5: "10", 2.5: "20", 1.5: "30", 4.5: "40", 5.5: "50"}, "--", "--and--", "30--20--10--40--and--50"},
+	} {
+		var result template.HTML
+		var err error
+		if this.last == nil {
+			result, err = Delimit(this.sequence, this.delimiter)
+		} else {
+			result, err = Delimit(this.sequence, this.delimiter, this.last)
+		}
+		if err != nil {
+			t.Errorf("[%d] failed: %s", i, err)
+			continue
+		}
+		if !reflect.DeepEqual(result, this.expect) {
+			t.Errorf("[%d] Delimit called on sequence: %v | delimiter: `%v` | last: `%v`, got %v but expected %v", i, this.sequence, this.delimiter, this.last, result, this.expect)
+		}
+	}
+}
+
+func TestSort(t *testing.T) {
+	type ts struct {
+		MyInt    int
+		MyFloat  float64
+		MyString string
+	}
+	for i, this := range []struct {
+		sequence    interface{}
+		sortByField interface{}
+		sortAsc     string
+		expect      []interface{}
+	}{
+		{[]string{"class1", "class2", "class3"}, nil, "asc", []interface{}{"class1", "class2", "class3"}},
+		{[]string{"class3", "class1", "class2"}, nil, "asc", []interface{}{"class1", "class2", "class3"}},
+		{[]int{1, 2, 3, 4, 5}, nil, "asc", []interface{}{1, 2, 3, 4, 5}},
+		{[]int{5, 4, 3, 1, 2}, nil, "asc", []interface{}{1, 2, 3, 4, 5}},
+		// test map sorting by keys
+		{map[string]int{"1": 10, "2": 20, "3": 30, "4": 40, "5": 50}, nil, "asc", []interface{}{10, 20, 30, 40, 50}},
+		{map[string]int{"3": 10, "2": 20, "1": 30, "4": 40, "5": 50}, nil, "asc", []interface{}{30, 20, 10, 40, 50}},
+		{map[string]string{"1": "10", "2": "20", "3": "30", "4": "40", "5": "50"}, nil, "asc", []interface{}{"10", "20", "30", "40", "50"}},
+		{map[string]string{"3": "10", "2": "20", "1": "30", "4": "40", "5": "50"}, nil, "asc", []interface{}{"30", "20", "10", "40", "50"}},
+		{map[string]string{"one": "10", "two": "20", "three": "30", "four": "40", "five": "50"}, nil, "asc", []interface{}{"50", "40", "10", "30", "20"}},
+		{map[int]string{1: "10", 2: "20", 3: "30", 4: "40", 5: "50"}, nil, "asc", []interface{}{"10", "20", "30", "40", "50"}},
+		{map[int]string{3: "10", 2: "20", 1: "30", 4: "40", 5: "50"}, nil, "asc", []interface{}{"30", "20", "10", "40", "50"}},
+		{map[float64]string{3.3: "10", 2.3: "20", 1.3: "30", 4.3: "40", 5.3: "50"}, nil, "asc", []interface{}{"30", "20", "10", "40", "50"}},
+		// test map sorting by value
+		{map[string]int{"1": 10, "2": 20, "3": 30, "4": 40, "5": 50}, "value", "asc", []interface{}{10, 20, 30, 40, 50}},
+		{map[string]int{"3": 10, "2": 20, "1": 30, "4": 40, "5": 50}, "value", "asc", []interface{}{10, 20, 30, 40, 50}},
+		// test map sorting by field value
+		{
+			map[string]ts{"1": {10, 10.5, "ten"}, "2": {20, 20.5, "twenty"}, "3": {30, 30.5, "thirty"}, "4": {40, 40.5, "forty"}, "5": {50, 50.5, "fifty"}},
+			"MyInt",
+			"asc",
+			[]interface{}{ts{10, 10.5, "ten"}, ts{20, 20.5, "twenty"}, ts{30, 30.5, "thirty"}, ts{40, 40.5, "forty"}, ts{50, 50.5, "fifty"}},
+		},
+		{
+			map[string]ts{"1": {10, 10.5, "ten"}, "2": {20, 20.5, "twenty"}, "3": {30, 30.5, "thirty"}, "4": {40, 40.5, "forty"}, "5": {50, 50.5, "fifty"}},
+			"MyFloat",
+			"asc",
+			[]interface{}{ts{10, 10.5, "ten"}, ts{20, 20.5, "twenty"}, ts{30, 30.5, "thirty"}, ts{40, 40.5, "forty"}, ts{50, 50.5, "fifty"}},
+		},
+		{
+			map[string]ts{"1": {10, 10.5, "ten"}, "2": {20, 20.5, "twenty"}, "3": {30, 30.5, "thirty"}, "4": {40, 40.5, "forty"}, "5": {50, 50.5, "fifty"}},
+			"MyString",
+			"asc",
+			[]interface{}{ts{50, 50.5, "fifty"}, ts{40, 40.5, "forty"}, ts{10, 10.5, "ten"}, ts{30, 30.5, "thirty"}, ts{20, 20.5, "twenty"}},
+		},
+		// Test sort desc
+		{[]string{"class1", "class2", "class3"}, "value", "desc", []interface{}{"class3", "class2", "class1"}},
+		{[]string{"class3", "class1", "class2"}, "value", "desc", []interface{}{"class3", "class2", "class1"}},
+	} {
+		var result []interface{}
+		var err error
+		if this.sortByField == nil {
+			result, err = Sort(this.sequence)
+		} else {
+			result, err = Sort(this.sequence, this.sortByField, this.sortAsc)
+		}
+		if err != nil {
+			t.Errorf("[%d] failed: %s", i, err)
+			continue
+		}
+		if !reflect.DeepEqual(result, this.expect) {
+			t.Errorf("[%d] Sort called on sequence: %v | sortByField: `%v` | got %v but expected %v", i, this.sequence, this.sortByField, result, this.expect)
+		}
+	}
+}
+
+func TestReturnWhenSet(t *testing.T) {
+	for i, this := range []struct {
+		data   interface{}
+		key    interface{}
+		expect interface{}
+	}{
+		{[]int{1, 2, 3}, 1, int64(2)},
+		{[]uint{1, 2, 3}, 1, uint64(2)},
+		{[]float64{1.1, 2.2, 3.3}, 1, float64(2.2)},
+		{[]string{"foo", "bar", "baz"}, 1, "bar"},
+		{[]TstX{{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"}}, 1, ""},
+		{map[string]int{"foo": 1, "bar": 2, "baz": 3}, "bar", int64(2)},
+		{map[string]uint{"foo": 1, "bar": 2, "baz": 3}, "bar", uint64(2)},
+		{map[string]float64{"foo": 1.1, "bar": 2.2, "baz": 3.3}, "bar", float64(2.2)},
+		{map[string]string{"foo": "FOO", "bar": "BAR", "baz": "BAZ"}, "bar", "BAR"},
+		{map[string]TstX{"foo": {A: "a", B: "b"}, "bar": {A: "c", B: "d"}, "baz": {A: "e", B: "f"}}, "bar", ""},
+		{(*[]string)(nil), "bar", ""},
+	} {
+		result := ReturnWhenSet(this.data, this.key)
+		if !reflect.DeepEqual(result, this.expect) {
+			t.Errorf("[%d] ReturnWhenSet got %v (type %v) but expected %v (type %v)", i, result, reflect.TypeOf(result), this.expect, reflect.TypeOf(this.expect))
+		}
+	}
+}
+
+func TestMarkdownify(t *testing.T) {
+
+	result := Markdownify("Hello **World!**")
+
+	expect := template.HTML("Hello <strong>World!</strong>")
+
+	if result != expect {
+		t.Errorf("Markdownify: got '%s', expected '%s'", result, expect)
+	}
+}
+
+func TestApply(t *testing.T) {
+	strings := []interface{}{"a\n", "b\n"}
+	noStringers := []interface{}{tstNoStringer{}, tstNoStringer{}}
+
+	var nilErr *error = nil
+
+	chomped, _ := Apply(strings, "chomp", ".")
+	assert.Equal(t, []interface{}{"a", "b"}, chomped)
+
+	chomped, _ = Apply(strings, "chomp", "c\n")
+	assert.Equal(t, []interface{}{"c", "c"}, chomped)
+
+	chomped, _ = Apply(nil, "chomp", ".")
+	assert.Equal(t, []interface{}{}, chomped)
+
+	_, err := Apply(strings, "apply", ".")
+	if err == nil {
+		t.Errorf("apply with apply should fail")
+	}
+
+	_, err = Apply(nilErr, "chomp", ".")
+	if err == nil {
+		t.Errorf("apply with nil in seq should fail")
+	}
+
+	_, err = Apply(strings, "dobedobedo", ".")
+	if err == nil {
+		t.Errorf("apply with unknown func should fail")
+	}
+
+	_, err = Apply(noStringers, "chomp", ".")
+	if err == nil {
+		t.Errorf("apply when func fails should fail")
+	}
+
+	_, err = Apply(tstNoStringer{}, "chomp", ".")
+	if err == nil {
+		t.Errorf("apply with non-sequence should fail")
+	}
+
+}
+
+func TestChomp(t *testing.T) {
+	base := "\n This is\na story "
+	for i, item := range []string{
+		"\n", "\n\n",
+		"\r", "\r\r",
+		"\r\n", "\r\n\r\n",
+	} {
+		chomped, _ := Chomp(base + item)
+
+		if chomped != base {
+			t.Errorf("[%d] Chomp failed, got '%v'", i, chomped)
+		}
+
+		_, err := Chomp(tstNoStringer{})
+
+		if err == nil {
+			t.Errorf("Chomp should fail")
+		}
+	}
+}
+
+func TestReplace(t *testing.T) {
+	v, _ := Replace("aab", "a", "b")
+	assert.Equal(t, "bbb", v)
+	v, _ = Replace("11a11", 1, 2)
+	assert.Equal(t, "22a22", v)
+	v, _ = Replace(12345, 1, 2)
+	assert.Equal(t, "22345", v)
+	_, e := Replace(tstNoStringer{}, "a", "b")
+	assert.NotNil(t, e, "tstNoStringer isn't trimmable")
+	_, e = Replace("a", tstNoStringer{}, "b")
+	assert.NotNil(t, e, "tstNoStringer cannot be converted to string")
+	_, e = Replace("a", "b", tstNoStringer{})
+	assert.NotNil(t, e, "tstNoStringer cannot be converted to string")
+}
+
+func TestTrim(t *testing.T) {
+	v, _ := Trim("1234 my way 13", "123")
+	assert.Equal(t, "4 my way ", v)
+	v, _ = Trim("   my way    ", " ")
+	assert.Equal(t, "my way", v)
+	v, _ = Trim(1234, "14")
+	assert.Equal(t, "23", v)
+	_, e := Trim(tstNoStringer{}, " ")
+	assert.NotNil(t, e, "tstNoStringer isn't trimmable")
+}
+
+func TestDateFormat(t *testing.T) {
+	for i, this := range []struct {
+		layout string
+		value  interface{}
+		expect interface{}
+	}{
+		{"Monday, Jan 2, 2006", "2015-01-21", "Wednesday, Jan 21, 2015"},
+		{"Monday, Jan 2, 2006", time.Date(2015, time.January, 21, 0, 0, 0, 0, time.UTC), "Wednesday, Jan 21, 2015"},
+		{"This isn't a date layout string", "2015-01-21", "This isn't a date layout string"},
+		{"Monday, Jan 2, 2006", 1421733600, false},
+		{"Monday, Jan 2, 2006", 1421733600.123, false},
+	} {
+		result, err := DateFormat(this.layout, this.value)
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] DateFormat didn't return an expected error", i)
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] DateFormat failed: %s", i, err)
+				continue
+			}
+			if result != this.expect {
+				t.Errorf("[%d] DateFormat got %v but expected %v", i, result, this.expect)
+			}
+		}
+	}
+}
+
+func TestSafeHTML(t *testing.T) {
+	for i, this := range []struct {
+		str                 string
+		tmplStr             string
+		expectWithoutEscape string
+		expectWithEscape    string
+	}{
+		{`<div></div>`, `{{ . }}`, `&lt;div&gt;&lt;/div&gt;`, `<div></div>`},
+	} {
+		tmpl, err := template.New("test").Parse(this.tmplStr)
+		if err != nil {
+			t.Errorf("[%d] unable to create new html template %q: %s", i, this.tmplStr, err)
+			continue
+		}
+
+		buf := new(bytes.Buffer)
+		err = tmpl.Execute(buf, this.str)
+		if err != nil {
+			t.Errorf("[%d] execute template with a raw string value returns unexpected error: %s", i, err)
+		}
+		if buf.String() != this.expectWithoutEscape {
+			t.Errorf("[%d] execute template with a raw string value, got %v but expected %v", i, buf.String(), this.expectWithoutEscape)
+		}
+
+		buf.Reset()
+		err = tmpl.Execute(buf, SafeHTML(this.str))
+		if err != nil {
+			t.Errorf("[%d] execute template with an escaped string value by SafeHTML returns unexpected error: %s", i, err)
+		}
+		if buf.String() != this.expectWithEscape {
+			t.Errorf("[%d] execute template with an escaped string value by SafeHTML, got %v but expected %v", i, buf.String(), this.expectWithEscape)
+		}
+	}
+}
+
+func TestSafeHTMLAttr(t *testing.T) {
+	for i, this := range []struct {
+		str                 string
+		tmplStr             string
+		expectWithoutEscape string
+		expectWithEscape    string
+	}{
+		{`href="irc://irc.freenode.net/#golang"`, `<a {{ . }}>irc</a>`, `<a ZgotmplZ>irc</a>`, `<a href="irc://irc.freenode.net/#golang">irc</a>`},
+	} {
+		tmpl, err := template.New("test").Parse(this.tmplStr)
+		if err != nil {
+			t.Errorf("[%d] unable to create new html template %q: %s", i, this.tmplStr, err)
+			continue
+		}
+
+		buf := new(bytes.Buffer)
+		err = tmpl.Execute(buf, this.str)
+		if err != nil {
+			t.Errorf("[%d] execute template with a raw string value returns unexpected error: %s", i, err)
+		}
+		if buf.String() != this.expectWithoutEscape {
+			t.Errorf("[%d] execute template with a raw string value, got %v but expected %v", i, buf.String(), this.expectWithoutEscape)
+		}
+
+		buf.Reset()
+		err = tmpl.Execute(buf, SafeHTMLAttr(this.str))
+		if err != nil {
+			t.Errorf("[%d] execute template with an escaped string value by SafeHTMLAttr returns unexpected error: %s", i, err)
+		}
+		if buf.String() != this.expectWithEscape {
+			t.Errorf("[%d] execute template with an escaped string value by SafeHTMLAttr, got %v but expected %v", i, buf.String(), this.expectWithEscape)
+		}
+	}
+}
+
+func TestSafeCSS(t *testing.T) {
+	for i, this := range []struct {
+		str                 string
+		tmplStr             string
+		expectWithoutEscape string
+		expectWithEscape    string
+	}{
+		{`width: 60px;`, `<div style="{{ . }}"></div>`, `<div style="ZgotmplZ"></div>`, `<div style="width: 60px;"></div>`},
+	} {
+		tmpl, err := template.New("test").Parse(this.tmplStr)
+		if err != nil {
+			t.Errorf("[%d] unable to create new html template %q: %s", i, this.tmplStr, err)
+			continue
+		}
+
+		buf := new(bytes.Buffer)
+		err = tmpl.Execute(buf, this.str)
+		if err != nil {
+			t.Errorf("[%d] execute template with a raw string value returns unexpected error: %s", i, err)
+		}
+		if buf.String() != this.expectWithoutEscape {
+			t.Errorf("[%d] execute template with a raw string value, got %v but expected %v", i, buf.String(), this.expectWithoutEscape)
+		}
+
+		buf.Reset()
+		err = tmpl.Execute(buf, SafeCSS(this.str))
+		if err != nil {
+			t.Errorf("[%d] execute template with an escaped string value by SafeCSS returns unexpected error: %s", i, err)
+		}
+		if buf.String() != this.expectWithEscape {
+			t.Errorf("[%d] execute template with an escaped string value by SafeCSS, got %v but expected %v", i, buf.String(), this.expectWithEscape)
+		}
+	}
+}
+
+func TestSafeURL(t *testing.T) {
+	for i, this := range []struct {
+		str                 string
+		tmplStr             string
+		expectWithoutEscape string
+		expectWithEscape    string
+	}{
+		{`irc://irc.freenode.net/#golang`, `<a href="{{ . }}">IRC</a>`, `<a href="#ZgotmplZ">IRC</a>`, `<a href="irc://irc.freenode.net/#golang">IRC</a>`},
+	} {
+		tmpl, err := template.New("test").Parse(this.tmplStr)
+		if err != nil {
+			t.Errorf("[%d] unable to create new html template %q: %s", i, this.tmplStr, err)
+			continue
+		}
+
+		buf := new(bytes.Buffer)
+		err = tmpl.Execute(buf, this.str)
+		if err != nil {
+			t.Errorf("[%d] execute template with a raw string value returns unexpected error: %s", i, err)
+		}
+		if buf.String() != this.expectWithoutEscape {
+			t.Errorf("[%d] execute template with a raw string value, got %v but expected %v", i, buf.String(), this.expectWithoutEscape)
+		}
+
+		buf.Reset()
+		err = tmpl.Execute(buf, SafeURL(this.str))
+		if err != nil {
+			t.Errorf("[%d] execute template with an escaped string value by SafeURL returns unexpected error: %s", i, err)
+		}
+		if buf.String() != this.expectWithEscape {
+			t.Errorf("[%d] execute template with an escaped string value by SafeURL, got %v but expected %v", i, buf.String(), this.expectWithEscape)
+		}
+	}
+}
--- a/tpl/template_test.go
+++ b/tpl/template_test.go
@@ -1,1222 +1,3 @@
 package tpl
 
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"github.com/stretchr/testify/assert"
-	"html/template"
-	"path"
-	"reflect"
-	"runtime"
-	"testing"
-	"time"
-)
-
-type tstNoStringer struct {
-}
-
-type tstCompareType int
-
-const (
-	tstEq tstCompareType = iota
-	tstNe
-	tstGt
-	tstGe
-	tstLt
-	tstLe
-)
-
-func tstIsEq(tp tstCompareType) bool {
-	return tp == tstEq || tp == tstGe || tp == tstLe
-}
-
-func tstIsGt(tp tstCompareType) bool {
-	return tp == tstGt || tp == tstGe
-}
-
-func tstIsLt(tp tstCompareType) bool {
-	return tp == tstLt || tp == tstLe
-}
-
-func TestCompare(t *testing.T) {
-	for _, this := range []struct {
-		tstCompareType
-		funcUnderTest func(a, b interface{}) bool
-	}{
-		{tstGt, Gt},
-		{tstLt, Lt},
-		{tstGe, Ge},
-		{tstLe, Le},
-		{tstEq, Eq},
-		{tstNe, Ne},
-	} {
-		doTestCompare(t, this.tstCompareType, this.funcUnderTest)
-	}
-
-}
-
-func doTestCompare(t *testing.T, tp tstCompareType, funcUnderTest func(a, b interface{}) bool) {
-	for i, this := range []struct {
-		left            interface{}
-		right           interface{}
-		expectIndicator int
-	}{
-		{5, 8, -1},
-		{8, 5, 1},
-		{5, 5, 0},
-		{int(5), int64(5), 0},
-		{int32(5), int(5), 0},
-		{int16(4), int(5), -1},
-		{uint(15), uint64(15), 0},
-		{-2, 1, -1},
-		{2, -5, 1},
-		{0.0, 1.23, -1},
-		{1.1, 1.1, 0},
-		{float32(1.0), float64(1.0), 0},
-		{1.23, 0.0, 1},
-		{"5", "5", 0},
-		{"8", "5", 1},
-		{"5", "0001", 1},
-		{[]int{100, 99}, []int{1, 2, 3, 4}, -1},
-	} {
-		result := funcUnderTest(this.left, this.right)
-		success := false
-
-		if this.expectIndicator == 0 {
-			if tstIsEq(tp) {
-				success = result
-			} else {
-				success = !result
-			}
-		}
-
-		if this.expectIndicator < 0 {
-			success = result && (tstIsLt(tp) || tp == tstNe)
-			success = success || (!result && !tstIsLt(tp))
-		}
-
-		if this.expectIndicator > 0 {
-			success = result && (tstIsGt(tp) || tp == tstNe)
-			success = success || (!result && (!tstIsGt(tp) || tp != tstNe))
-		}
-
-		if !success {
-			t.Errorf("[%d][%s] %v compared to %v: %t", i, path.Base(runtime.FuncForPC(reflect.ValueOf(funcUnderTest).Pointer()).Name()), this.left, this.right, result)
-		}
-	}
-}
-
-func TestArethmic(t *testing.T) {
-	for i, this := range []struct {
-		a      interface{}
-		b      interface{}
-		op     rune
-		expect interface{}
-	}{
-		{1, 2, '+', int64(3)},
-		{1, 2, '-', int64(-1)},
-		{2, 2, '*', int64(4)},
-		{4, 2, '/', int64(2)},
-		{uint8(1), uint8(3), '+', uint64(4)},
-		{uint8(3), uint8(2), '-', uint64(1)},
-		{uint8(2), uint8(2), '*', uint64(4)},
-		{uint16(4), uint8(2), '/', uint64(2)},
-		{4, 2, '¤', false},
-		{4, 0, '/', false},
-	} {
-		// TODO(bep): Take precision into account.
-		result, err := doArithmetic(this.a, this.b, this.op)
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] doArethmic didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if !reflect.DeepEqual(result, this.expect) {
-				t.Errorf("[%d] doArethmic got %v (%T) but expected %v (%T)", i, result, result, this.expect, this.expect)
-			}
-		}
-	}
-}
-
-func TestMod(t *testing.T) {
-	for i, this := range []struct {
-		a      interface{}
-		b      interface{}
-		expect interface{}
-	}{
-		{3, 2, int64(1)},
-		{3, 1, int64(0)},
-		{3, 0, false},
-		{0, 3, int64(0)},
-		{3.1, 2, false},
-		{3, 2.1, false},
-		{3.1, 2.1, false},
-		{int8(3), int8(2), int64(1)},
-		{int16(3), int16(2), int64(1)},
-		{int32(3), int32(2), int64(1)},
-		{int64(3), int64(2), int64(1)},
-	} {
-		result, err := Mod(this.a, this.b)
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] modulo didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if !reflect.DeepEqual(result, this.expect) {
-				t.Errorf("[%d] modulo got %v but expected %v", i, result, this.expect)
-			}
-		}
-	}
-}
-
-func TestModBool(t *testing.T) {
-	for i, this := range []struct {
-		a      interface{}
-		b      interface{}
-		expect interface{}
-	}{
-		{3, 3, true},
-		{3, 2, false},
-		{3, 1, true},
-		{3, 0, nil},
-		{0, 3, true},
-		{3.1, 2, nil},
-		{3, 2.1, nil},
-		{3.1, 2.1, nil},
-		{int8(3), int8(3), true},
-		{int8(3), int8(2), false},
-		{int16(3), int16(3), true},
-		{int16(3), int16(2), false},
-		{int32(3), int32(3), true},
-		{int32(3), int32(2), false},
-		{int64(3), int64(3), true},
-		{int64(3), int64(2), false},
-	} {
-		result, err := ModBool(this.a, this.b)
-		if this.expect == nil {
-			if err == nil {
-				t.Errorf("[%d] modulo didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if !reflect.DeepEqual(result, this.expect) {
-				t.Errorf("[%d] modulo got %v but expected %v", i, result, this.expect)
-			}
-		}
-	}
-}
-
-func TestFirst(t *testing.T) {
-	for i, this := range []struct {
-		count    interface{}
-		sequence interface{}
-		expect   interface{}
-	}{
-		{int(2), []string{"a", "b", "c"}, []string{"a", "b"}},
-		{int32(3), []string{"a", "b"}, []string{"a", "b"}},
-		{int64(2), []int{100, 200, 300}, []int{100, 200}},
-		{100, []int{100, 200}, []int{100, 200}},
-		{"1", []int{100, 200, 300}, []int{100}},
-		{int64(-1), []int{100, 200, 300}, false},
-		{"noint", []int{100, 200, 300}, false},
-		{1, nil, false},
-		{nil, []int{100}, false},
-		{1, t, false},
-	} {
-		results, err := First(this.count, this.sequence)
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] First didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if !reflect.DeepEqual(results, this.expect) {
-				t.Errorf("[%d] First %d items, got %v but expected %v", i, this.count, results, this.expect)
-			}
-		}
-	}
-}
-
-func TestIn(t *testing.T) {
-	for i, this := range []struct {
-		v1     interface{}
-		v2     interface{}
-		expect bool
-	}{
-		{[]string{"a", "b", "c"}, "b", true},
-		{[]string{"a", "b", "c"}, "d", false},
-		{[]string{"a", "12", "c"}, 12, false},
-		{[]int{1, 2, 4}, 2, true},
-		{[]int{1, 2, 4}, 3, false},
-		{[]float64{1.23, 2.45, 4.67}, 1.23, true},
-		{[]float64{1.234567, 2.45, 4.67}, 1.234568, false},
-		{"this substring should be found", "substring", true},
-		{"this substring should not be found", "subseastring", false},
-	} {
-		result := In(this.v1, this.v2)
-
-		if result != this.expect {
-			t.Errorf("[%d] Got %v but expected %v", i, result, this.expect)
-		}
-	}
-}
-
-func TestSlicestr(t *testing.T) {
-	for i, this := range []struct {
-		v1     interface{}
-		v2     []int
-		expect interface{}
-	}{
-		{"abc", []int{1, 2}, "b"},
-		{"abc", []int{1, 3}, "bc"},
-		{"abc", []int{0, 1}, "a"},
-		{"abcdef", []int{}, "abcdef"},
-		{"abcdef", []int{0, 6}, "abcdef"},
-		{"abcdef", []int{0, 2}, "ab"},
-		{"abcdef", []int{2}, "cdef"},
-		{123, []int{1, 3}, "23"},
-		{123, []int{1, 2, 3}, false},
-		{tstNoStringer{}, []int{0, 1}, false},
-	} {
-		result, err := Slicestr(this.v1, this.v2...)
-
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] Slice didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if !reflect.DeepEqual(result, this.expect) {
-				t.Errorf("[%d] Got %s but expected %s", i, result, this.expect)
-			}
-		}
-	}
-}
-
-func TestSubstr(t *testing.T) {
-	for i, this := range []struct {
-		v1     interface{}
-		v2     int
-		v3     int
-		expect interface{}
-	}{
-		{"abc", 1, 2, "bc"},
-		{"abc", 0, 1, "a"},
-		{"abcdef", -1, 2, "ef"},
-		{"abcdef", -3, 3, "bcd"},
-		{"abcdef", 0, -1, "abcde"},
-		{"abcdef", 2, -1, "cde"},
-		{"abcdef", 4, -4, false},
-		{"abcdef", 7, 1, false},
-		{"abcdef", 1, 100, "bcdef"},
-		{"abcdef", -100, 3, "abc"},
-		{"abcdef", -3, -1, "de"},
-		{123, 1, 3, "23"},
-		{1.2e3, 0, 4, "1200"},
-		{tstNoStringer{}, 0, 1, false},
-	} {
-		result, err := Substr(this.v1, this.v2, this.v3)
-
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] Substr didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if !reflect.DeepEqual(result, this.expect) {
-				t.Errorf("[%d] Got %s but expected %s", i, result, this.expect)
-			}
-		}
-	}
-}
-
-func TestSplit(t *testing.T) {
-	for i, this := range []struct {
-		v1     interface{}
-		v2     string
-		expect interface{}
-	}{
-		{"a, b", ", ", []string{"a", "b"}},
-		{"a & b & c", " & ", []string{"a", "b", "c"}},
-		{"http://exmaple.com", "http://", []string{"", "exmaple.com"}},
-		{123, "2", []string{"1", "3"}},
-		{tstNoStringer{}, ",", false},
-	} {
-		result, err := Split(this.v1, this.v2)
-
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] Split didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if !reflect.DeepEqual(result, this.expect) {
-				t.Errorf("[%d] Got %s but expected %s", i, result, this.expect)
-			}
-		}
-	}
-
-}
-
-func TestIntersect(t *testing.T) {
-	for i, this := range []struct {
-		sequence1 interface{}
-		sequence2 interface{}
-		expect    interface{}
-	}{
-		{[]string{"a", "b", "c"}, []string{"a", "b"}, []string{"a", "b"}},
-		{[]string{"a", "b"}, []string{"a", "b", "c"}, []string{"a", "b"}},
-		{[]string{"a", "b", "c"}, []string{"d", "e"}, []string{}},
-		{[]string{}, []string{}, []string{}},
-		{[]string{"a", "b"}, nil, make([]interface{}, 0)},
-		{nil, []string{"a", "b"}, make([]interface{}, 0)},
-		{nil, nil, make([]interface{}, 0)},
-		{[]string{"1", "2"}, []int{1, 2}, []string{}},
-		{[]int{1, 2}, []string{"1", "2"}, []int{}},
-		{[]int{1, 2, 4}, []int{2, 4}, []int{2, 4}},
-		{[]int{2, 4}, []int{1, 2, 4}, []int{2, 4}},
-		{[]int{1, 2, 4}, []int{3, 6}, []int{}},
-		{[]float64{2.2, 4.4}, []float64{1.1, 2.2, 4.4}, []float64{2.2, 4.4}},
-	} {
-		results, err := Intersect(this.sequence1, this.sequence2)
-		if err != nil {
-			t.Errorf("[%d] failed: %s", i, err)
-			continue
-		}
-		if !reflect.DeepEqual(results, this.expect) {
-			t.Errorf("[%d] Got %v but expected %v", i, results, this.expect)
-		}
-	}
-
-	_, err1 := Intersect("not an array or slice", []string{"a"})
-
-	if err1 == nil {
-		t.Error("Excpected error for non array as first arg")
-	}
-
-	_, err2 := Intersect([]string{"a"}, "not an array or slice")
-
-	if err2 == nil {
-		t.Error("Excpected error for non array as second arg")
-	}
-}
-
-func TestIsSet(t *testing.T) {
-	aSlice := []interface{}{1, 2, 3, 5}
-	aMap := map[string]interface{}{"a": 1, "b": 2}
-
-	assert.True(t, IsSet(aSlice, 2))
-	assert.True(t, IsSet(aMap, "b"))
-	assert.False(t, IsSet(aSlice, 22))
-	assert.False(t, IsSet(aMap, "bc"))
-}
-
-func (x *TstX) TstRp() string {
-	return "r" + x.A
-}
-
-func (x TstX) TstRv() string {
-	return "r" + x.B
-}
-
-func (x TstX) unexportedMethod() string {
-	return x.unexported
-}
-
-func (x TstX) MethodWithArg(s string) string {
-	return s
-}
-
-func (x TstX) MethodReturnNothing() {}
-
-func (x TstX) MethodReturnErrorOnly() error {
-	return errors.New("something error occured")
-}
-
-func (x TstX) MethodReturnTwoValues() (string, string) {
-	return "foo", "bar"
-}
-
-func (x TstX) MethodReturnValueWithError() (string, error) {
-	return "", errors.New("something error occured")
-}
-
-func (x TstX) String() string {
-	return fmt.Sprintf("A: %s, B: %s", x.A, x.B)
-}
-
-type TstX struct {
-	A, B       string
-	unexported string
-}
-
-func TestEvaluateSubElem(t *testing.T) {
-	tstx := TstX{A: "foo", B: "bar"}
-	var inner struct {
-		S fmt.Stringer
-	}
-	inner.S = tstx
-	interfaceValue := reflect.ValueOf(&inner).Elem().Field(0)
-
-	for i, this := range []struct {
-		value  reflect.Value
-		key    string
-		expect interface{}
-	}{
-		{reflect.ValueOf(tstx), "A", "foo"},
-		{reflect.ValueOf(&tstx), "TstRp", "rfoo"},
-		{reflect.ValueOf(tstx), "TstRv", "rbar"},
-		//{reflect.ValueOf(map[int]string{1: "foo", 2: "bar"}), 1, "foo"},
-		{reflect.ValueOf(map[string]string{"key1": "foo", "key2": "bar"}), "key1", "foo"},
-		{interfaceValue, "String", "A: foo, B: bar"},
-		{reflect.Value{}, "foo", false},
-		//{reflect.ValueOf(map[int]string{1: "foo", 2: "bar"}), 1.2, false},
-		{reflect.ValueOf(tstx), "unexported", false},
-		{reflect.ValueOf(tstx), "unexportedMethod", false},
-		{reflect.ValueOf(tstx), "MethodWithArg", false},
-		{reflect.ValueOf(tstx), "MethodReturnNothing", false},
-		{reflect.ValueOf(tstx), "MethodReturnErrorOnly", false},
-		{reflect.ValueOf(tstx), "MethodReturnTwoValues", false},
-		{reflect.ValueOf(tstx), "MethodReturnValueWithError", false},
-		{reflect.ValueOf((*TstX)(nil)), "A", false},
-		{reflect.ValueOf(tstx), "C", false},
-		{reflect.ValueOf(map[int]string{1: "foo", 2: "bar"}), "1", false},
-		{reflect.ValueOf([]string{"foo", "bar"}), "1", false},
-	} {
-		result, err := evaluateSubElem(this.value, this.key)
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] evaluateSubElem didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if result.Kind() != reflect.String || result.String() != this.expect {
-				t.Errorf("[%d] evaluateSubElem with %v got %v but expected %v", i, this.key, result, this.expect)
-			}
-		}
-	}
-}
-
-func TestCheckCondition(t *testing.T) {
-	type expect struct {
-		result  bool
-		isError bool
-	}
-
-	for i, this := range []struct {
-		value reflect.Value
-		match reflect.Value
-		op    string
-		expect
-	}{
-		{reflect.ValueOf(123), reflect.ValueOf(123), "", expect{true, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf("foo"), "", expect{true, false}},
-		{reflect.ValueOf(123), reflect.ValueOf(456), "!=", expect{true, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf("bar"), "!=", expect{true, false}},
-		{reflect.ValueOf(456), reflect.ValueOf(123), ">=", expect{true, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf("bar"), ">=", expect{true, false}},
-		{reflect.ValueOf(456), reflect.ValueOf(123), ">", expect{true, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf("bar"), ">", expect{true, false}},
-		{reflect.ValueOf(123), reflect.ValueOf(456), "<=", expect{true, false}},
-		{reflect.ValueOf("bar"), reflect.ValueOf("foo"), "<=", expect{true, false}},
-		{reflect.ValueOf(123), reflect.ValueOf(456), "<", expect{true, false}},
-		{reflect.ValueOf("bar"), reflect.ValueOf("foo"), "<", expect{true, false}},
-		{reflect.ValueOf(123), reflect.ValueOf([]int{123, 45, 678}), "in", expect{true, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf([]string{"foo", "bar", "baz"}), "in", expect{true, false}},
-		{reflect.ValueOf(123), reflect.ValueOf([]int{45, 678}), "not in", expect{true, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf([]string{"bar", "baz"}), "not in", expect{true, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf("bar-foo-baz"), "in", expect{true, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf("bar--baz"), "not in", expect{true, false}},
-		{reflect.Value{}, reflect.ValueOf("foo"), "", expect{false, false}},
-		{reflect.ValueOf("foo"), reflect.Value{}, "", expect{false, false}},
-		{reflect.ValueOf((*TstX)(nil)), reflect.ValueOf("foo"), "", expect{false, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf((*TstX)(nil)), "", expect{false, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf(map[int]string{}), "", expect{false, false}},
-		{reflect.ValueOf("foo"), reflect.ValueOf([]int{1, 2}), "", expect{false, false}},
-		{reflect.ValueOf(123), reflect.ValueOf([]int{}), "in", expect{false, false}},
-		{reflect.ValueOf(123), reflect.ValueOf(123), "op", expect{false, true}},
-	} {
-		result, err := checkCondition(this.value, this.match, this.op)
-		if this.expect.isError {
-			if err == nil {
-				t.Errorf("[%d] checkCondition didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if result != this.expect.result {
-				t.Errorf("[%d] check condition %v %s %v, got %v but expected %v", i, this.value, this.op, this.match, result, this.expect.result)
-			}
-		}
-	}
-}
-
-func TestWhere(t *testing.T) {
-	// TODO(spf): Put these page tests back in
-	//page1 := &Page{contentType: "v", Source: Source{File: *source.NewFile("/x/y/z/source.md")}}
-	//page2 := &Page{contentType: "w", Source: Source{File: *source.NewFile("/y/z/a/source.md")}}
-
-	type Mid struct {
-		Tst TstX
-	}
-
-	for i, this := range []struct {
-		sequence interface{}
-		key      interface{}
-		op       string
-		match    interface{}
-		expect   interface{}
-	}{
-		{
-			sequence: []map[int]string{
-				{1: "a", 2: "m"}, {1: "c", 2: "d"}, {1: "e", 3: "m"},
-			},
-			key: 2, match: "m",
-			expect: []map[int]string{
-				{1: "a", 2: "m"},
-			},
-		},
-		{
-			sequence: []map[string]int{
-				{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4},
-			},
-			key: "b", match: 4,
-			expect: []map[string]int{
-				{"a": 3, "b": 4},
-			},
-		},
-		{
-			sequence: []TstX{
-				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
-			},
-			key: "B", match: "f",
-			expect: []TstX{
-				{A: "e", B: "f"},
-			},
-		},
-		{
-			sequence: []*map[int]string{
-				{1: "a", 2: "m"}, {1: "c", 2: "d"}, {1: "e", 3: "m"},
-			},
-			key: 2, match: "m",
-			expect: []*map[int]string{
-				{1: "a", 2: "m"},
-			},
-		},
-		{
-			sequence: []*TstX{
-				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
-			},
-			key: "B", match: "f",
-			expect: []*TstX{
-				{A: "e", B: "f"},
-			},
-		},
-		{
-			sequence: []*TstX{
-				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "c"},
-			},
-			key: "TstRp", match: "rc",
-			expect: []*TstX{
-				{A: "c", B: "d"},
-			},
-		},
-		{
-			sequence: []TstX{
-				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "c"},
-			},
-			key: "TstRv", match: "rc",
-			expect: []TstX{
-				{A: "e", B: "c"},
-			},
-		},
-		{
-			sequence: []map[string]TstX{
-				{"foo": TstX{A: "a", B: "b"}}, {"foo": TstX{A: "c", B: "d"}}, {"foo": TstX{A: "e", B: "f"}},
-			},
-			key: "foo.B", match: "d",
-			expect: []map[string]TstX{
-				{"foo": TstX{A: "c", B: "d"}},
-			},
-		},
-		{
-			sequence: []map[string]TstX{
-				{"foo": TstX{A: "a", B: "b"}}, {"foo": TstX{A: "c", B: "d"}}, {"foo": TstX{A: "e", B: "f"}},
-			},
-			key: ".foo.B", match: "d",
-			expect: []map[string]TstX{
-				{"foo": TstX{A: "c", B: "d"}},
-			},
-		},
-		{
-			sequence: []map[string]TstX{
-				{"foo": TstX{A: "a", B: "b"}}, {"foo": TstX{A: "c", B: "d"}}, {"foo": TstX{A: "e", B: "f"}},
-			},
-			key: "foo.TstRv", match: "rd",
-			expect: []map[string]TstX{
-				{"foo": TstX{A: "c", B: "d"}},
-			},
-		},
-		{
-			sequence: []map[string]*TstX{
-				{"foo": &TstX{A: "a", B: "b"}}, {"foo": &TstX{A: "c", B: "d"}}, {"foo": &TstX{A: "e", B: "f"}},
-			},
-			key: "foo.TstRp", match: "rc",
-			expect: []map[string]*TstX{
-				{"foo": &TstX{A: "c", B: "d"}},
-			},
-		},
-		{
-			sequence: []map[string]Mid{
-				{"foo": Mid{Tst: TstX{A: "a", B: "b"}}}, {"foo": Mid{Tst: TstX{A: "c", B: "d"}}}, {"foo": Mid{Tst: TstX{A: "e", B: "f"}}},
-			},
-			key: "foo.Tst.B", match: "d",
-			expect: []map[string]Mid{
-				{"foo": Mid{Tst: TstX{A: "c", B: "d"}}},
-			},
-		},
-		{
-			sequence: []map[string]Mid{
-				{"foo": Mid{Tst: TstX{A: "a", B: "b"}}}, {"foo": Mid{Tst: TstX{A: "c", B: "d"}}}, {"foo": Mid{Tst: TstX{A: "e", B: "f"}}},
-			},
-			key: "foo.Tst.TstRv", match: "rd",
-			expect: []map[string]Mid{
-				{"foo": Mid{Tst: TstX{A: "c", B: "d"}}},
-			},
-		},
-		{
-			sequence: []map[string]*Mid{
-				{"foo": &Mid{Tst: TstX{A: "a", B: "b"}}}, {"foo": &Mid{Tst: TstX{A: "c", B: "d"}}}, {"foo": &Mid{Tst: TstX{A: "e", B: "f"}}},
-			},
-			key: "foo.Tst.TstRp", match: "rc",
-			expect: []map[string]*Mid{
-				{"foo": &Mid{Tst: TstX{A: "c", B: "d"}}},
-			},
-		},
-		{
-			sequence: []map[string]int{
-				{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6},
-			},
-			key: "b", op: ">", match: 3,
-			expect: []map[string]int{
-				{"a": 3, "b": 4}, {"a": 5, "b": 6},
-			},
-		},
-		{
-			sequence: []TstX{
-				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
-			},
-			key: "B", op: "!=", match: "f",
-			expect: []TstX{
-				{A: "a", B: "b"}, {A: "c", B: "d"},
-			},
-		},
-		{
-			sequence: []map[string]int{
-				{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "b": 6},
-			},
-			key: "b", op: "in", match: []int{3, 4, 5},
-			expect: []map[string]int{
-				{"a": 3, "b": 4},
-			},
-		},
-		{
-			sequence: []TstX{
-				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
-			},
-			key: "B", op: "not in", match: []string{"c", "d", "e"},
-			expect: []TstX{
-				{A: "a", B: "b"}, {A: "e", B: "f"},
-			},
-		},
-		{sequence: (*[]TstX)(nil), key: "A", match: "a", expect: false},
-		{sequence: TstX{A: "a", B: "b"}, key: "A", match: "a", expect: false},
-		{sequence: []map[string]*TstX{{"foo": nil}}, key: "foo.B", match: "d", expect: false},
-		{
-			sequence: []TstX{
-				{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"},
-			},
-			key: "B", op: "op", match: "f",
-			expect: false,
-		},
-		//{[]*Page{page1, page2}, "Type", "v", []*Page{page1}},
-		//{[]*Page{page1, page2}, "Section", "y", []*Page{page2}},
-	} {
-		var results interface{}
-		var err error
-		if len(this.op) > 0 {
-			results, err = Where(this.sequence, this.key, this.op, this.match)
-		} else {
-			results, err = Where(this.sequence, this.key, this.match)
-		}
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] Where didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if !reflect.DeepEqual(results, this.expect) {
-				t.Errorf("[%d] Where clause matching %v with %v, got %v but expected %v", i, this.key, this.match, results, this.expect)
-			}
-		}
-	}
-
-	var err error
-	_, err = Where(map[string]int{"a": 1, "b": 2}, "a", []byte("="), 1)
-	if err == nil {
-		t.Errorf("Where called with none string op value didn't return an expected error")
-	}
-
-	_, err = Where(map[string]int{"a": 1, "b": 2}, "a", []byte("="), 1, 2)
-	if err == nil {
-		t.Errorf("Where called with more than two variable arguments didn't return an expected error")
-	}
-
-	_, err = Where(map[string]int{"a": 1, "b": 2}, "a")
-	if err == nil {
-		t.Errorf("Where called with no variable arguments didn't return an expected error")
-	}
-}
-
-func TestDelimit(t *testing.T) {
-	for i, this := range []struct {
-		sequence  interface{}
-		delimiter interface{}
-		last      interface{}
-		expect    template.HTML
-	}{
-		{[]string{"class1", "class2", "class3"}, " ", nil, "class1 class2 class3"},
-		{[]int{1, 2, 3, 4, 5}, ",", nil, "1,2,3,4,5"},
-		{[]int{1, 2, 3, 4, 5}, ", ", nil, "1, 2, 3, 4, 5"},
-		{[]string{"class1", "class2", "class3"}, " ", " and ", "class1 class2 and class3"},
-		{[]int{1, 2, 3, 4, 5}, ",", ",", "1,2,3,4,5"},
-		{[]int{1, 2, 3, 4, 5}, ", ", ", and ", "1, 2, 3, 4, and 5"},
-		// test maps with and without sorting required
-		{map[string]int{"1": 10, "2": 20, "3": 30, "4": 40, "5": 50}, "--", nil, "10--20--30--40--50"},
-		{map[string]int{"3": 10, "2": 20, "1": 30, "4": 40, "5": 50}, "--", nil, "30--20--10--40--50"},
-		{map[string]string{"1": "10", "2": "20", "3": "30", "4": "40", "5": "50"}, "--", nil, "10--20--30--40--50"},
-		{map[string]string{"3": "10", "2": "20", "1": "30", "4": "40", "5": "50"}, "--", nil, "30--20--10--40--50"},
-		{map[string]string{"one": "10", "two": "20", "three": "30", "four": "40", "five": "50"}, "--", nil, "50--40--10--30--20"},
-		{map[int]string{1: "10", 2: "20", 3: "30", 4: "40", 5: "50"}, "--", nil, "10--20--30--40--50"},
-		{map[int]string{3: "10", 2: "20", 1: "30", 4: "40", 5: "50"}, "--", nil, "30--20--10--40--50"},
-		{map[float64]string{3.3: "10", 2.3: "20", 1.3: "30", 4.3: "40", 5.3: "50"}, "--", nil, "30--20--10--40--50"},
-		// test maps with a last delimiter
-		{map[string]int{"1": 10, "2": 20, "3": 30, "4": 40, "5": 50}, "--", "--and--", "10--20--30--40--and--50"},
-		{map[string]int{"3": 10, "2": 20, "1": 30, "4": 40, "5": 50}, "--", "--and--", "30--20--10--40--and--50"},
-		{map[string]string{"1": "10", "2": "20", "3": "30", "4": "40", "5": "50"}, "--", "--and--", "10--20--30--40--and--50"},
-		{map[string]string{"3": "10", "2": "20", "1": "30", "4": "40", "5": "50"}, "--", "--and--", "30--20--10--40--and--50"},
-		{map[string]string{"one": "10", "two": "20", "three": "30", "four": "40", "five": "50"}, "--", "--and--", "50--40--10--30--and--20"},
-		{map[int]string{1: "10", 2: "20", 3: "30", 4: "40", 5: "50"}, "--", "--and--", "10--20--30--40--and--50"},
-		{map[int]string{3: "10", 2: "20", 1: "30", 4: "40", 5: "50"}, "--", "--and--", "30--20--10--40--and--50"},
-		{map[float64]string{3.5: "10", 2.5: "20", 1.5: "30", 4.5: "40", 5.5: "50"}, "--", "--and--", "30--20--10--40--and--50"},
-	} {
-		var result template.HTML
-		var err error
-		if this.last == nil {
-			result, err = Delimit(this.sequence, this.delimiter)
-		} else {
-			result, err = Delimit(this.sequence, this.delimiter, this.last)
-		}
-		if err != nil {
-			t.Errorf("[%d] failed: %s", i, err)
-			continue
-		}
-		if !reflect.DeepEqual(result, this.expect) {
-			t.Errorf("[%d] Delimit called on sequence: %v | delimiter: `%v` | last: `%v`, got %v but expected %v", i, this.sequence, this.delimiter, this.last, result, this.expect)
-		}
-	}
-}
-
-func TestSort(t *testing.T) {
-	type ts struct {
-		MyInt    int
-		MyFloat  float64
-		MyString string
-	}
-	for i, this := range []struct {
-		sequence    interface{}
-		sortByField interface{}
-		sortAsc     string
-		expect      []interface{}
-	}{
-		{[]string{"class1", "class2", "class3"}, nil, "asc", []interface{}{"class1", "class2", "class3"}},
-		{[]string{"class3", "class1", "class2"}, nil, "asc", []interface{}{"class1", "class2", "class3"}},
-		{[]int{1, 2, 3, 4, 5}, nil, "asc", []interface{}{1, 2, 3, 4, 5}},
-		{[]int{5, 4, 3, 1, 2}, nil, "asc", []interface{}{1, 2, 3, 4, 5}},
-		// test map sorting by keys
-		{map[string]int{"1": 10, "2": 20, "3": 30, "4": 40, "5": 50}, nil, "asc", []interface{}{10, 20, 30, 40, 50}},
-		{map[string]int{"3": 10, "2": 20, "1": 30, "4": 40, "5": 50}, nil, "asc", []interface{}{30, 20, 10, 40, 50}},
-		{map[string]string{"1": "10", "2": "20", "3": "30", "4": "40", "5": "50"}, nil, "asc", []interface{}{"10", "20", "30", "40", "50"}},
-		{map[string]string{"3": "10", "2": "20", "1": "30", "4": "40", "5": "50"}, nil, "asc", []interface{}{"30", "20", "10", "40", "50"}},
-		{map[string]string{"one": "10", "two": "20", "three": "30", "four": "40", "five": "50"}, nil, "asc", []interface{}{"50", "40", "10", "30", "20"}},
-		{map[int]string{1: "10", 2: "20", 3: "30", 4: "40", 5: "50"}, nil, "asc", []interface{}{"10", "20", "30", "40", "50"}},
-		{map[int]string{3: "10", 2: "20", 1: "30", 4: "40", 5: "50"}, nil, "asc", []interface{}{"30", "20", "10", "40", "50"}},
-		{map[float64]string{3.3: "10", 2.3: "20", 1.3: "30", 4.3: "40", 5.3: "50"}, nil, "asc", []interface{}{"30", "20", "10", "40", "50"}},
-		// test map sorting by value
-		{map[string]int{"1": 10, "2": 20, "3": 30, "4": 40, "5": 50}, "value", "asc", []interface{}{10, 20, 30, 40, 50}},
-		{map[string]int{"3": 10, "2": 20, "1": 30, "4": 40, "5": 50}, "value", "asc", []interface{}{10, 20, 30, 40, 50}},
-		// test map sorting by field value
-		{
-			map[string]ts{"1": {10, 10.5, "ten"}, "2": {20, 20.5, "twenty"}, "3": {30, 30.5, "thirty"}, "4": {40, 40.5, "forty"}, "5": {50, 50.5, "fifty"}},
-			"MyInt",
-			"asc",
-			[]interface{}{ts{10, 10.5, "ten"}, ts{20, 20.5, "twenty"}, ts{30, 30.5, "thirty"}, ts{40, 40.5, "forty"}, ts{50, 50.5, "fifty"}},
-		},
-		{
-			map[string]ts{"1": {10, 10.5, "ten"}, "2": {20, 20.5, "twenty"}, "3": {30, 30.5, "thirty"}, "4": {40, 40.5, "forty"}, "5": {50, 50.5, "fifty"}},
-			"MyFloat",
-			"asc",
-			[]interface{}{ts{10, 10.5, "ten"}, ts{20, 20.5, "twenty"}, ts{30, 30.5, "thirty"}, ts{40, 40.5, "forty"}, ts{50, 50.5, "fifty"}},
-		},
-		{
-			map[string]ts{"1": {10, 10.5, "ten"}, "2": {20, 20.5, "twenty"}, "3": {30, 30.5, "thirty"}, "4": {40, 40.5, "forty"}, "5": {50, 50.5, "fifty"}},
-			"MyString",
-			"asc",
-			[]interface{}{ts{50, 50.5, "fifty"}, ts{40, 40.5, "forty"}, ts{10, 10.5, "ten"}, ts{30, 30.5, "thirty"}, ts{20, 20.5, "twenty"}},
-		},
-		// Test sort desc
-		{[]string{"class1", "class2", "class3"}, "value", "desc", []interface{}{"class3", "class2", "class1"}},
-		{[]string{"class3", "class1", "class2"}, "value", "desc", []interface{}{"class3", "class2", "class1"}},
-	} {
-		var result []interface{}
-		var err error
-		if this.sortByField == nil {
-			result, err = Sort(this.sequence)
-		} else {
-			result, err = Sort(this.sequence, this.sortByField, this.sortAsc)
-		}
-		if err != nil {
-			t.Errorf("[%d] failed: %s", i, err)
-			continue
-		}
-		if !reflect.DeepEqual(result, this.expect) {
-			t.Errorf("[%d] Sort called on sequence: %v | sortByField: `%v` | got %v but expected %v", i, this.sequence, this.sortByField, result, this.expect)
-		}
-	}
-}
-
-func TestReturnWhenSet(t *testing.T) {
-	for i, this := range []struct {
-		data   interface{}
-		key    interface{}
-		expect interface{}
-	}{
-		{[]int{1, 2, 3}, 1, int64(2)},
-		{[]uint{1, 2, 3}, 1, uint64(2)},
-		{[]float64{1.1, 2.2, 3.3}, 1, float64(2.2)},
-		{[]string{"foo", "bar", "baz"}, 1, "bar"},
-		{[]TstX{{A: "a", B: "b"}, {A: "c", B: "d"}, {A: "e", B: "f"}}, 1, ""},
-		{map[string]int{"foo": 1, "bar": 2, "baz": 3}, "bar", int64(2)},
-		{map[string]uint{"foo": 1, "bar": 2, "baz": 3}, "bar", uint64(2)},
-		{map[string]float64{"foo": 1.1, "bar": 2.2, "baz": 3.3}, "bar", float64(2.2)},
-		{map[string]string{"foo": "FOO", "bar": "BAR", "baz": "BAZ"}, "bar", "BAR"},
-		{map[string]TstX{"foo": {A: "a", B: "b"}, "bar": {A: "c", B: "d"}, "baz": {A: "e", B: "f"}}, "bar", ""},
-		{(*[]string)(nil), "bar", ""},
-	} {
-		result := ReturnWhenSet(this.data, this.key)
-		if !reflect.DeepEqual(result, this.expect) {
-			t.Errorf("[%d] ReturnWhenSet got %v (type %v) but expected %v (type %v)", i, result, reflect.TypeOf(result), this.expect, reflect.TypeOf(this.expect))
-		}
-	}
-}
-
-func TestMarkdownify(t *testing.T) {
-
-	result := Markdownify("Hello **World!**")
-
-	expect := template.HTML("Hello <strong>World!</strong>")
-
-	if result != expect {
-		t.Errorf("Markdownify: got '%s', expected '%s'", result, expect)
-	}
-}
-
-func TestApply(t *testing.T) {
-	strings := []interface{}{"a\n", "b\n"}
-	noStringers := []interface{}{tstNoStringer{}, tstNoStringer{}}
-
-	var nilErr *error = nil
-
-	chomped, _ := Apply(strings, "chomp", ".")
-	assert.Equal(t, []interface{}{"a", "b"}, chomped)
-
-	chomped, _ = Apply(strings, "chomp", "c\n")
-	assert.Equal(t, []interface{}{"c", "c"}, chomped)
-
-	chomped, _ = Apply(nil, "chomp", ".")
-	assert.Equal(t, []interface{}{}, chomped)
-
-	_, err := Apply(strings, "apply", ".")
-	if err == nil {
-		t.Errorf("apply with apply should fail")
-	}
-
-	_, err = Apply(nilErr, "chomp", ".")
-	if err == nil {
-		t.Errorf("apply with nil in seq should fail")
-	}
-
-	_, err = Apply(strings, "dobedobedo", ".")
-	if err == nil {
-		t.Errorf("apply with unknown func should fail")
-	}
-
-	_, err = Apply(noStringers, "chomp", ".")
-	if err == nil {
-		t.Errorf("apply when func fails should fail")
-	}
-
-	_, err = Apply(tstNoStringer{}, "chomp", ".")
-	if err == nil {
-		t.Errorf("apply with non-sequence should fail")
-	}
-
-}
-
-func TestChomp(t *testing.T) {
-	base := "\n This is\na story "
-	for i, item := range []string{
-		"\n", "\n\n",
-		"\r", "\r\r",
-		"\r\n", "\r\n\r\n",
-	} {
-		chomped, _ := Chomp(base + item)
-
-		if chomped != base {
-			t.Errorf("[%d] Chomp failed, got '%v'", i, chomped)
-		}
-
-		_, err := Chomp(tstNoStringer{})
-
-		if err == nil {
-			t.Errorf("Chomp should fail")
-		}
-	}
-}
-
-func TestReplace(t *testing.T) {
-	v, _ := Replace("aab", "a", "b")
-	assert.Equal(t, "bbb", v)
-	v, _ = Replace("11a11", 1, 2)
-	assert.Equal(t, "22a22", v)
-	v, _ = Replace(12345, 1, 2)
-	assert.Equal(t, "22345", v)
-	_, e := Replace(tstNoStringer{}, "a", "b")
-	assert.NotNil(t, e, "tstNoStringer isn't trimmable")
-	_, e = Replace("a", tstNoStringer{}, "b")
-	assert.NotNil(t, e, "tstNoStringer cannot be converted to string")
-	_, e = Replace("a", "b", tstNoStringer{})
-	assert.NotNil(t, e, "tstNoStringer cannot be converted to string")
-}
-
-func TestTrim(t *testing.T) {
-	v, _ := Trim("1234 my way 13", "123")
-	assert.Equal(t, "4 my way ", v)
-	v, _ = Trim("   my way    ", " ")
-	assert.Equal(t, "my way", v)
-	v, _ = Trim(1234, "14")
-	assert.Equal(t, "23", v)
-	_, e := Trim(tstNoStringer{}, " ")
-	assert.NotNil(t, e, "tstNoStringer isn't trimmable")
-}
-
-func TestDateFormat(t *testing.T) {
-	for i, this := range []struct {
-		layout string
-		value  interface{}
-		expect interface{}
-	}{
-		{"Monday, Jan 2, 2006", "2015-01-21", "Wednesday, Jan 21, 2015"},
-		{"Monday, Jan 2, 2006", time.Date(2015, time.January, 21, 0, 0, 0, 0, time.UTC), "Wednesday, Jan 21, 2015"},
-		{"This isn't a date layout string", "2015-01-21", "This isn't a date layout string"},
-		{"Monday, Jan 2, 2006", 1421733600, false},
-		{"Monday, Jan 2, 2006", 1421733600.123, false},
-	} {
-		result, err := DateFormat(this.layout, this.value)
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] DateFormat didn't return an expected error", i)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] DateFormat failed: %s", i, err)
-				continue
-			}
-			if result != this.expect {
-				t.Errorf("[%d] DateFormat got %v but expected %v", i, result, this.expect)
-			}
-		}
-	}
-}
-
-func TestSafeHTML(t *testing.T) {
-	for i, this := range []struct {
-		str                 string
-		tmplStr             string
-		expectWithoutEscape string
-		expectWithEscape    string
-	}{
-		{`<div></div>`, `{{ . }}`, `&lt;div&gt;&lt;/div&gt;`, `<div></div>`},
-	} {
-		tmpl, err := template.New("test").Parse(this.tmplStr)
-		if err != nil {
-			t.Errorf("[%d] unable to create new html template %q: %s", i, this.tmplStr, err)
-			continue
-		}
-
-		buf := new(bytes.Buffer)
-		err = tmpl.Execute(buf, this.str)
-		if err != nil {
-			t.Errorf("[%d] execute template with a raw string value returns unexpected error: %s", i, err)
-		}
-		if buf.String() != this.expectWithoutEscape {
-			t.Errorf("[%d] execute template with a raw string value, got %v but expected %v", i, buf.String(), this.expectWithoutEscape)
-		}
-
-		buf.Reset()
-		err = tmpl.Execute(buf, SafeHTML(this.str))
-		if err != nil {
-			t.Errorf("[%d] execute template with an escaped string value by SafeHTML returns unexpected error: %s", i, err)
-		}
-		if buf.String() != this.expectWithEscape {
-			t.Errorf("[%d] execute template with an escaped string value by SafeHTML, got %v but expected %v", i, buf.String(), this.expectWithEscape)
-		}
-	}
-}
-
-func TestSafeHTMLAttr(t *testing.T) {
-	for i, this := range []struct {
-		str                 string
-		tmplStr             string
-		expectWithoutEscape string
-		expectWithEscape    string
-	}{
-		{`href="irc://irc.freenode.net/#golang"`, `<a {{ . }}>irc</a>`, `<a ZgotmplZ>irc</a>`, `<a href="irc://irc.freenode.net/#golang">irc</a>`},
-	} {
-		tmpl, err := template.New("test").Parse(this.tmplStr)
-		if err != nil {
-			t.Errorf("[%d] unable to create new html template %q: %s", i, this.tmplStr, err)
-			continue
-		}
-
-		buf := new(bytes.Buffer)
-		err = tmpl.Execute(buf, this.str)
-		if err != nil {
-			t.Errorf("[%d] execute template with a raw string value returns unexpected error: %s", i, err)
-		}
-		if buf.String() != this.expectWithoutEscape {
-			t.Errorf("[%d] execute template with a raw string value, got %v but expected %v", i, buf.String(), this.expectWithoutEscape)
-		}
-
-		buf.Reset()
-		err = tmpl.Execute(buf, SafeHTMLAttr(this.str))
-		if err != nil {
-			t.Errorf("[%d] execute template with an escaped string value by SafeHTMLAttr returns unexpected error: %s", i, err)
-		}
-		if buf.String() != this.expectWithEscape {
-			t.Errorf("[%d] execute template with an escaped string value by SafeHTMLAttr, got %v but expected %v", i, buf.String(), this.expectWithEscape)
-		}
-	}
-}
-
-func TestSafeCSS(t *testing.T) {
-	for i, this := range []struct {
-		str                 string
-		tmplStr             string
-		expectWithoutEscape string
-		expectWithEscape    string
-	}{
-		{`width: 60px;`, `<div style="{{ . }}"></div>`, `<div style="ZgotmplZ"></div>`, `<div style="width: 60px;"></div>`},
-	} {
-		tmpl, err := template.New("test").Parse(this.tmplStr)
-		if err != nil {
-			t.Errorf("[%d] unable to create new html template %q: %s", i, this.tmplStr, err)
-			continue
-		}
-
-		buf := new(bytes.Buffer)
-		err = tmpl.Execute(buf, this.str)
-		if err != nil {
-			t.Errorf("[%d] execute template with a raw string value returns unexpected error: %s", i, err)
-		}
-		if buf.String() != this.expectWithoutEscape {
-			t.Errorf("[%d] execute template with a raw string value, got %v but expected %v", i, buf.String(), this.expectWithoutEscape)
-		}
-
-		buf.Reset()
-		err = tmpl.Execute(buf, SafeCSS(this.str))
-		if err != nil {
-			t.Errorf("[%d] execute template with an escaped string value by SafeCSS returns unexpected error: %s", i, err)
-		}
-		if buf.String() != this.expectWithEscape {
-			t.Errorf("[%d] execute template with an escaped string value by SafeCSS, got %v but expected %v", i, buf.String(), this.expectWithEscape)
-		}
-	}
-}
-
-func TestSafeURL(t *testing.T) {
-	for i, this := range []struct {
-		str                 string
-		tmplStr             string
-		expectWithoutEscape string
-		expectWithEscape    string
-	}{
-		{`irc://irc.freenode.net/#golang`, `<a href="{{ . }}">IRC</a>`, `<a href="#ZgotmplZ">IRC</a>`, `<a href="irc://irc.freenode.net/#golang">IRC</a>`},
-	} {
-		tmpl, err := template.New("test").Parse(this.tmplStr)
-		if err != nil {
-			t.Errorf("[%d] unable to create new html template %q: %s", i, this.tmplStr, err)
-			continue
-		}
-
-		buf := new(bytes.Buffer)
-		err = tmpl.Execute(buf, this.str)
-		if err != nil {
-			t.Errorf("[%d] execute template with a raw string value returns unexpected error: %s", i, err)
-		}
-		if buf.String() != this.expectWithoutEscape {
-			t.Errorf("[%d] execute template with a raw string value, got %v but expected %v", i, buf.String(), this.expectWithoutEscape)
-		}
-
-		buf.Reset()
-		err = tmpl.Execute(buf, SafeURL(this.str))
-		if err != nil {
-			t.Errorf("[%d] execute template with an escaped string value by SafeURL returns unexpected error: %s", i, err)
-		}
-		if buf.String() != this.expectWithEscape {
-			t.Errorf("[%d] execute template with an escaped string value by SafeURL, got %v but expected %v", i, buf.String(), this.expectWithEscape)
-		}
-	}
-}
+// TODO(bep) test it