shithub: hugo

Download patch

ref: 73f203ad86a71136a1d35e0aa1bba574edb91a51
parent: 92a3372a3fdc0365a06a75e6d97f24e624db879b
author: spf13 <[email protected]>
date: Thu Nov 20 07:32:21 EST 2014

Move template library into it's own package (tpl). No longer dependent on hugolib. Can be used externally.

--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -17,10 +17,6 @@
 	"bytes"
 	"errors"
 	"fmt"
-	"github.com/spf13/hugo/helpers"
-	"github.com/spf13/hugo/parser"
-	jww "github.com/spf13/jwalterweatherman"
-	"github.com/spf13/viper"
 	"html/template"
 	"io"
 	"net/url"
@@ -29,8 +25,13 @@
 	"time"
 
 	"github.com/spf13/cast"
+	"github.com/spf13/hugo/helpers"
 	"github.com/spf13/hugo/hugofs"
+	"github.com/spf13/hugo/parser"
 	"github.com/spf13/hugo/source"
+	"github.com/spf13/hugo/tpl"
+	jww "github.com/spf13/jwalterweatherman"
+	"github.com/spf13/viper"
 )
 
 type Page struct {
@@ -44,7 +45,7 @@
 	Truncated       bool
 	Draft           bool
 	PublishDate     time.Time
-	Tmpl            Template
+	Tmpl            tpl.Template
 	Markup          string
 
 	extension         string
@@ -528,7 +529,7 @@
 		curLayout = layout[0]
 	}
 
-	return ExecuteTemplateToHTML(p, p.Layout(curLayout)...)
+	return tpl.ExecuteTemplateToHTML(p, p.Layout(curLayout)...)
 }
 
 func (page *Page) guessMarkupType() string {
@@ -629,7 +630,7 @@
 	return page.SaveSourceAs(page.FullFilePath())
 }
 
-func (p *Page) ProcessShortcodes(t Template) {
+func (p *Page) ProcessShortcodes(t tpl.Template) {
 
 	// these short codes aren't used until after Page render,
 	// but processed here to avoid coupling
--- a/hugolib/shortcode.go
+++ b/hugolib/shortcode.go
@@ -16,8 +16,6 @@
 import (
 	"bytes"
 	"fmt"
-	"github.com/spf13/hugo/helpers"
-	jww "github.com/spf13/jwalterweatherman"
 	"html/template"
 	"reflect"
 	"regexp"
@@ -24,6 +22,10 @@
 	"sort"
 	"strconv"
 	"strings"
+
+	"github.com/spf13/hugo/helpers"
+	"github.com/spf13/hugo/tpl"
+	jww "github.com/spf13/jwalterweatherman"
 )
 
 type ShortcodeFunc func([]string) string
@@ -117,7 +119,7 @@
 
 // all in  one go: extract, render and replace
 // only used for testing
-func ShortcodesHandle(stringToParse string, page *Page, t Template) string {
+func ShortcodesHandle(stringToParse string, page *Page, t tpl.Template) string {
 
 	tmpContent, tmpShortcodes := extractAndRenderShortcodes(stringToParse, page, t)
 
@@ -154,7 +156,7 @@
 	return fmt.Sprintf("<div>%s-%d</div>", shortcodePlaceholderPrefix, id)
 }
 
-func renderShortcodes(sc shortcode, p *Page, t Template) string {
+func renderShortcodes(sc shortcode, p *Page, t tpl.Template) string {
 
 	tokenizedRenderedShortcodes := make(map[string](string))
 	startCount := 0
@@ -169,7 +171,7 @@
 	return shortcodes
 }
 
-func renderShortcode(sc shortcode, tokenizedShortcodes map[string](string), cnt int, p *Page, t Template) string {
+func renderShortcode(sc shortcode, tokenizedShortcodes map[string](string), cnt int, p *Page, t tpl.Template) string {
 	var data = &ShortcodeWithPage{Params: sc.params, Page: p}
 	tmpl := GetTemplate(sc.name, t)
 
@@ -209,7 +211,7 @@
 	return ShortcodeRender(tmpl, data)
 }
 
-func extractAndRenderShortcodes(stringToParse string, p *Page, t Template) (string, map[string]string) {
+func extractAndRenderShortcodes(stringToParse string, p *Page, t tpl.Template) (string, map[string]string) {
 
 	content, shortcodes, err := extractShortcodes(stringToParse, p, t)
 	renderedShortcodes := make(map[string]string)
@@ -235,7 +237,7 @@
 // pageTokens state:
 // - before: positioned just before the shortcode start
 // - after: shortcode(s) consumed (plural when they are nested)
-func extractShortcode(pt *pageTokens, p *Page, t Template) (shortcode, error) {
+func extractShortcode(pt *pageTokens, p *Page, t tpl.Template) (shortcode, error) {
 	sc := shortcode{}
 	var isInner = false
 
@@ -334,7 +336,7 @@
 	return sc, nil
 }
 
-func extractShortcodes(stringToParse string, p *Page, t Template) (string, map[string]shortcode, error) {
+func extractShortcodes(stringToParse string, p *Page, t tpl.Template) (string, map[string]shortcode, error) {
 
 	shortCodes := make(map[string]shortcode)
 
@@ -452,7 +454,7 @@
 	return buff[0:width], nil
 }
 
-func GetTemplate(name string, t Template) *template.Template {
+func GetTemplate(name string, t tpl.Template) *template.Template {
 	if x := t.Lookup("shortcodes/" + name + ".html"); x != nil {
 		return x
 	}
--- a/hugolib/shortcode_test.go
+++ b/hugolib/shortcode_test.go
@@ -2,13 +2,15 @@
 
 import (
 	"fmt"
-	"github.com/spf13/hugo/helpers"
-	"github.com/spf13/viper"
 	"reflect"
 	"regexp"
 	"sort"
 	"strings"
 	"testing"
+
+	"github.com/spf13/hugo/helpers"
+	"github.com/spf13/hugo/tpl"
+	"github.com/spf13/viper"
 )
 
 func pageFromString(in, filename string) (*Page, error) {
@@ -15,7 +17,7 @@
 	return NewPageFrom(strings.NewReader(in), filename)
 }
 
-func CheckShortCodeMatch(t *testing.T, input, expected string, template Template) {
+func CheckShortCodeMatch(t *testing.T, input, expected string, template tpl.Template) {
 
 	p, _ := pageFromString(SIMPLE_PAGE, "simple.md")
 	output := ShortcodesHandle(input, p, template)
@@ -26,13 +28,13 @@
 }
 
 func TestNonSC(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	// notice the syntax diff from 0.12, now comment delims must be added
 	CheckShortCodeMatch(t, "{{%/* movie 47238zzb */%}}", "{{% movie 47238zzb %}}", tem)
 }
 
 func TestPositionalParamSC(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	tem.AddInternalShortcode("video.html", `Playing Video {{ .Get 0 }}`)
 
 	CheckShortCodeMatch(t, "{{< video 47238zzb >}}", "Playing Video 47238zzb", tem)
@@ -43,7 +45,7 @@
 }
 
 func TestNamedParamSC(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	tem.AddInternalShortcode("img.html", `<img{{ with .Get "src" }} src="{{.}}"{{end}}{{with .Get "class"}} class="{{.}}"{{end}}>`)
 
 	CheckShortCodeMatch(t, `{{< img src="one" >}}`, `<img src="one">`, tem)
@@ -55,7 +57,7 @@
 }
 
 func TestInnerSC(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`)
 
 	CheckShortCodeMatch(t, `{{< inside class="aspen" >}}`, `<div class="aspen"></div>`, tem)
@@ -64,7 +66,7 @@
 }
 
 func TestInnerSCWithMarkdown(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`)
 
 	CheckShortCodeMatch(t, `{{% inside %}}
@@ -76,7 +78,7 @@
 }
 
 func TestInnerSCWithAndWithoutMarkdown(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`)
 
 	CheckShortCodeMatch(t, `{{% inside %}}
@@ -98,7 +100,7 @@
 }
 
 func TestEmbeddedSC(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	CheckShortCodeMatch(t, "{{% test %}}", "This is a simple Test", tem)
 	CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" %}}`, "\n<figure class=\"bananas orange\">\n    \n        <img src=\"/found/here\" />\n    \n    \n</figure>\n", tem)
 	CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" caption="This is a caption" %}}`, "\n<figure class=\"bananas orange\">\n    \n        <img src=\"/found/here\" alt=\"This is a caption\" />\n    \n    \n    <figcaption>\n        <p>\n        This is a caption\n        \n            \n        \n        </p> \n    </figcaption>\n    \n</figure>\n", tem)
@@ -105,7 +107,7 @@
 }
 
 func TestNestedSC(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	tem.AddInternalShortcode("scn1.html", `<div>Outer, inner is {{ .Inner }}</div>`)
 	tem.AddInternalShortcode("scn2.html", `<div>SC2</div>`)
 
@@ -113,7 +115,7 @@
 }
 
 func TestNestedComplexSC(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	tem.AddInternalShortcode("row.html", `-row-{{ .Inner}}-rowStop-`)
 	tem.AddInternalShortcode("column.html", `-col-{{.Inner    }}-colStop-`)
 	tem.AddInternalShortcode("aside.html", `-aside-{{    .Inner  }}-asideStop-`)
@@ -127,7 +129,7 @@
 }
 
 func TestFigureImgWidth(t *testing.T) {
-	tem := NewTemplate()
+	tem := tpl.New()
 	CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" width="100px" %}}`, "\n<figure class=\"bananas orange\">\n    \n        <img src=\"/found/here\" alt=\"apple\" width=\"100px\" />\n    \n    \n</figure>\n", tem)
 }
 
@@ -138,7 +140,7 @@
 	defer viper.Set("PygmentsStyle", viper.Get("PygmentsStyle"))
 	viper.Set("PygmentsStyle", "bw")
 
-	tem := NewTemplate()
+	tem := tpl.New()
 
 	code := `
 {{< highlight java >}}
@@ -196,7 +198,7 @@
 	} {
 
 		p, _ := pageFromString(SIMPLE_PAGE, "simple.md")
-		tem := NewTemplate()
+		tem := tpl.New()
 		tem.AddInternalShortcode("tag.html", `tag`)
 		tem.AddInternalShortcode("sc1.html", `sc1`)
 		tem.AddInternalShortcode("sc2.html", `sc2`)
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -31,6 +31,7 @@
 	"github.com/spf13/hugo/hugofs"
 	"github.com/spf13/hugo/source"
 	"github.com/spf13/hugo/target"
+	"github.com/spf13/hugo/tpl"
 	"github.com/spf13/hugo/transform"
 	jww "github.com/spf13/jwalterweatherman"
 	"github.com/spf13/nitro"
@@ -61,7 +62,7 @@
 type Site struct {
 	Pages       Pages
 	Files       []*source.File
-	Tmpl        Template
+	Tmpl        tpl.Template
 	Taxonomies  TaxonomyList
 	Source      source.Input
 	Sections    Taxonomy
@@ -166,7 +167,7 @@
 }
 
 func (s *Site) prepTemplates() {
-	s.Tmpl = NewTemplate()
+	s.Tmpl = tpl.T()
 	s.Tmpl.LoadTemplates(s.absLayoutDir())
 	if s.hasTheme() {
 		s.Tmpl.LoadTemplatesWithPrefix(s.absThemeDir()+"/layouts", "theme")
--- a/hugolib/site_test.go
+++ b/hugolib/site_test.go
@@ -13,6 +13,7 @@
 	"github.com/spf13/hugo/hugofs"
 	"github.com/spf13/hugo/source"
 	"github.com/spf13/hugo/target"
+	"github.com/spf13/hugo/tpl"
 	"github.com/spf13/viper"
 )
 
@@ -46,6 +47,14 @@
 `
 )
 
+func templatePrep(s *Site) {
+	s.Tmpl = tpl.New()
+	s.Tmpl.LoadTemplates(s.absLayoutDir())
+	if s.hasTheme() {
+		s.Tmpl.LoadTemplatesWithPrefix(s.absThemeDir()+"/layouts", "theme")
+	}
+}
+
 func pageMust(p *Page, err error) *Page {
 	if err != nil {
 		panic(err)
@@ -57,7 +66,7 @@
 	p, _ := NewPageFrom(strings.NewReader(PAGE_SIMPLE_TITLE), "content/a/file.md")
 	p.Convert()
 	s := new(Site)
-	s.prepTemplates()
+	templatePrep(s)
 	err := s.renderThing(p, "foobar", nil)
 	if err == nil {
 		t.Errorf("Expected err to be returned when missing the template.")
@@ -66,7 +75,7 @@
 
 func TestAddInvalidTemplate(t *testing.T) {
 	s := new(Site)
-	s.prepTemplates()
+	templatePrep(s)
 	err := s.addTemplate("missing", TEMPLATE_MISSING_FUNC)
 	if err == nil {
 		t.Fatalf("Expecting the template to return an error")
@@ -108,7 +117,7 @@
 	}
 
 	s := new(Site)
-	s.prepTemplates()
+	templatePrep(s)
 
 	for i, test := range tests {
 		p, err := NewPageFrom(strings.NewReader(test.content), "content/a/file.md")
@@ -154,7 +163,7 @@
 
 	hugofs.DestinationFS = new(afero.MemMapFs)
 	s := &Site{}
-	s.prepTemplates()
+	templatePrep(s)
 
 	for i, test := range tests {
 		p, err := NewPageFrom(strings.NewReader(PAGE_SIMPLE_TITLE), "content/a/file.md")
@@ -306,7 +315,7 @@
 	}
 
 	s.initializeSiteInfo()
-	s.prepTemplates()
+	templatePrep(s)
 
 	must(s.addTemplate("_default/single.html", "{{.Content}}"))
 	must(s.addTemplate("head", "<head><script src=\"script.js\"></script></head>"))
@@ -366,7 +375,7 @@
 		}
 		t.Logf("Rendering with BaseUrl %q and CanonifyUrls set %v", viper.GetString("baseUrl"), canonify)
 		s.initializeSiteInfo()
-		s.prepTemplates()
+		templatePrep(s)
 		must(s.addTemplate("blue/single.html", TEMPLATE_WITH_URL_ABS))
 
 		if err := s.CreatePages(); err != nil {
--- a/hugolib/template.go
+++ /dev/null
@@ -1,690 +1,0 @@
-package hugolib
-
-import (
-	"bytes"
-	"errors"
-	"html"
-	"html/template"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"reflect"
-	"strconv"
-	"strings"
-
-	"github.com/eknkc/amber"
-	"github.com/spf13/cast"
-	"github.com/spf13/hugo/helpers"
-	jww "github.com/spf13/jwalterweatherman"
-)
-
-var localTemplates *template.Template
-
-func Eq(x, y interface{}) bool {
-	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
-	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, _ = strconv.ParseFloat(av.String(), 64)
-	}
-
-	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, _ = strconv.ParseFloat(bv.String(), 64)
-	}
-
-	return left, right
-}
-
-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
-}
-
-// First is exposed to templates, to iterate over the first N items in a
-// rangeable list.
-func First(limit interface{}, seq interface{}) (interface{}, error) {
-
-	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)
-	// this is better than my first pass; ripped from text/template/exec.go indirect():
-	for ; seqv.Kind() == reflect.Ptr || seqv.Kind() == reflect.Interface; seqv = seqv.Elem() {
-		if seqv.IsNil() {
-			return nil, errors.New("can't iterate over a nil value")
-		}
-		if seqv.Kind() == reflect.Interface && seqv.NumMethod() > 0 {
-			break
-		}
-	}
-
-	switch seqv.Kind() {
-	case reflect.Array, reflect.Slice, reflect.String:
-		// okay
-	default:
-		return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
-	}
-	if limitv > seqv.Len() {
-		limitv = seqv.Len()
-	}
-	return seqv.Slice(0, limitv).Interface(), nil
-}
-
-func Where(seq, key, match interface{}) (interface{}, error) {
-	seqv := reflect.ValueOf(seq)
-	kv := reflect.ValueOf(key)
-	mv := reflect.ValueOf(match)
-
-	// this is better than my first pass; ripped from text/template/exec.go indirect():
-	for ; seqv.Kind() == reflect.Ptr || seqv.Kind() == reflect.Interface; seqv = seqv.Elem() {
-		if seqv.IsNil() {
-			return nil, errors.New("can't iterate over a nil value")
-		}
-		if seqv.Kind() == reflect.Interface && seqv.NumMethod() > 0 {
-			break
-		}
-	}
-
-	switch seqv.Kind() {
-	case reflect.Array, reflect.Slice:
-		r := reflect.MakeSlice(seqv.Type(), 0, 0)
-		for i := 0; i < seqv.Len(); i++ {
-			var vvv reflect.Value
-			vv := seqv.Index(i)
-			switch vv.Kind() {
-			case reflect.Map:
-				if kv.Type() == vv.Type().Key() && vv.MapIndex(kv).IsValid() {
-					vvv = vv.MapIndex(kv)
-				}
-			case reflect.Struct:
-				if kv.Kind() == reflect.String {
-					method := vv.MethodByName(kv.String())
-					if method.IsValid() && method.Type().NumIn() == 0 && method.Type().NumOut() > 0 {
-						vvv = method.Call(nil)[0]
-					} else if vv.FieldByName(kv.String()).IsValid() {
-						vvv = vv.FieldByName(kv.String())
-					}
-				}
-			case reflect.Ptr:
-				if !vv.IsNil() {
-					ev := vv.Elem()
-					switch ev.Kind() {
-					case reflect.Map:
-						if kv.Type() == ev.Type().Key() && ev.MapIndex(kv).IsValid() {
-							vvv = ev.MapIndex(kv)
-						}
-					case reflect.Struct:
-						if kv.Kind() == reflect.String {
-							method := vv.MethodByName(kv.String())
-							if method.IsValid() && method.Type().NumIn() == 0 && method.Type().NumOut() > 0 {
-								vvv = method.Call(nil)[0]
-							} else if ev.FieldByName(kv.String()).IsValid() {
-								vvv = ev.FieldByName(kv.String())
-							}
-						}
-					}
-				}
-			}
-
-			if vvv.IsValid() && mv.Type() == vvv.Type() {
-				switch mv.Kind() {
-				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-					if mv.Int() == vvv.Int() {
-						r = reflect.Append(r, vv)
-					}
-				case reflect.String:
-					if mv.String() == vvv.String() {
-						r = reflect.Append(r, vv)
-					}
-				}
-			}
-		}
-		return r.Interface(), nil
-	default:
-		return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
-	}
-}
-
-func IsSet(a interface{}, key interface{}) bool {
-	av := reflect.ValueOf(a)
-	kv := reflect.ValueOf(key)
-
-	switch av.Kind() {
-	case reflect.Array, reflect.Chan, reflect.Slice:
-		if int64(av.Len()) > kv.Int() {
-			return true
-		}
-	case reflect.Map:
-		if kv.Type() == av.Type().Key() {
-			return av.MapIndex(kv).IsValid()
-		}
-	}
-
-	return false
-}
-
-func ReturnWhenSet(a interface{}, index int) interface{} {
-	av := reflect.ValueOf(a)
-
-	switch av.Kind() {
-	case reflect.Array, reflect.Slice:
-		if av.Len() > index {
-
-			avv := av.Index(index)
-			switch avv.Kind() {
-			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-				return avv.Int()
-			case reflect.String:
-				return avv.String()
-			}
-		}
-	}
-
-	return ""
-}
-
-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))
-}
-
-func SafeHtml(text string) template.HTML {
-	return template.HTML(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
-}
-
-type Template interface {
-	ExecuteTemplate(wr io.Writer, name string, data interface{}) error
-	Lookup(name string) *template.Template
-	Templates() []*template.Template
-	New(name string) *template.Template
-	LoadTemplates(absPath string)
-	LoadTemplatesWithPrefix(absPath, prefix string)
-	AddTemplate(name, tpl string) error
-	AddInternalTemplate(prefix, name, tpl string) error
-	AddInternalShortcode(name, tpl string) error
-}
-
-type templateErr struct {
-	name string
-	err  error
-}
-
-type GoHtmlTemplate struct {
-	template.Template
-	errors []*templateErr
-}
-
-func NewTemplate() Template {
-	var templates = &GoHtmlTemplate{
-		Template: *template.New(""),
-		errors:   make([]*templateErr, 0),
-	}
-
-	localTemplates = &templates.Template
-
-	funcMap := template.FuncMap{
-		"urlize":      helpers.Urlize,
-		"sanitizeurl": helpers.SanitizeUrl,
-		"eq":          Eq,
-		"ne":          Ne,
-		"gt":          Gt,
-		"ge":          Ge,
-		"lt":          Lt,
-		"le":          Le,
-		"in":          In,
-		"intersect":   Intersect,
-		"isset":       IsSet,
-		"echoParam":   ReturnWhenSet,
-		"safeHtml":    SafeHtml,
-		"first":       First,
-		"where":       Where,
-		"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,
-	}
-
-	templates.Funcs(funcMap)
-
-	templates.LoadEmbedded()
-	return templates
-}
-
-func Partial(name string, context_list ...interface{}) template.HTML {
-	if strings.HasPrefix("partials/", name) {
-		name = name[8:]
-	}
-	var context interface{}
-
-	if len(context_list) == 0 {
-		context = nil
-	} else {
-		context = context_list[0]
-	}
-	return ExecuteTemplateToHTML(context, "partials/"+name, "theme/partials/"+name)
-}
-
-func ExecuteTemplate(context interface{}, layouts ...string) *bytes.Buffer {
-	buffer := new(bytes.Buffer)
-	worked := false
-	for _, layout := range layouts {
-		name := layout
-
-		if localTemplates.Lookup(name) == nil {
-			name = layout + ".html"
-		}
-
-		if localTemplates.Lookup(name) != nil {
-			err := localTemplates.ExecuteTemplate(buffer, name, context)
-			if err != nil {
-				jww.ERROR.Println(err, "in", name)
-			}
-			worked = true
-			break
-		}
-	}
-	if !worked {
-		jww.ERROR.Println("Unable to render", layouts)
-		jww.ERROR.Println("Expecting to find a template in either the theme/layouts or /layouts in one of the following relative locations", layouts)
-	}
-
-	return buffer
-}
-
-func ExecuteTemplateToHTML(context interface{}, layouts ...string) template.HTML {
-	b := ExecuteTemplate(context, layouts...)
-	return template.HTML(string(b.Bytes()))
-}
-
-func (t *GoHtmlTemplate) LoadEmbedded() {
-	t.EmbedShortcodes()
-	t.EmbedTemplates()
-}
-
-func (t *GoHtmlTemplate) AddInternalTemplate(prefix, name, tpl string) error {
-	if prefix != "" {
-		return t.AddTemplate("_internal/"+prefix+"/"+name, tpl)
-	} else {
-		return t.AddTemplate("_internal/"+name, tpl)
-	}
-}
-
-func (t *GoHtmlTemplate) AddInternalShortcode(name, content string) error {
-	return t.AddInternalTemplate("shortcodes", name, content)
-}
-
-func (t *GoHtmlTemplate) AddTemplate(name, tpl string) error {
-	_, err := t.New(name).Parse(tpl)
-	if err != nil {
-		t.errors = append(t.errors, &templateErr{name: name, err: err})
-	}
-	return err
-}
-
-func (t *GoHtmlTemplate) AddTemplateFile(name, path string) error {
-	// get the suffix and switch on that
-	ext := filepath.Ext(path)
-	switch ext {
-	case ".amber":
-		compiler := amber.New()
-		// Parse the input file
-		if err := compiler.ParseFile(path); err != nil {
-			return nil
-		}
-
-		if _, err := compiler.CompileWithTemplate(t.New(name)); err != nil {
-			return err
-		}
-	default:
-		b, err := ioutil.ReadFile(path)
-		if err != nil {
-			return err
-		}
-
-		return t.AddTemplate(name, string(b))
-	}
-
-	return nil
-
-}
-
-func (t *GoHtmlTemplate) generateTemplateNameFrom(base, path string) string {
-	return filepath.ToSlash(path[len(base)+1:])
-}
-
-func ignoreDotFile(path string) bool {
-	return filepath.Base(path)[0] == '.'
-}
-
-func (t *GoHtmlTemplate) loadTemplates(absPath string, prefix string) {
-	walker := func(path string, fi os.FileInfo, err error) error {
-		if err != nil {
-			return nil
-		}
-
-		if !fi.IsDir() {
-			if ignoreDotFile(path) {
-				return nil
-			}
-
-			tplName := t.generateTemplateNameFrom(absPath, path)
-
-			if prefix != "" {
-				tplName = strings.Trim(prefix, "/") + "/" + tplName
-			}
-
-			t.AddTemplateFile(tplName, path)
-
-		}
-		return nil
-	}
-
-	filepath.Walk(absPath, walker)
-}
-
-func (t *GoHtmlTemplate) LoadTemplatesWithPrefix(absPath string, prefix string) {
-	t.loadTemplates(absPath, prefix)
-}
-
-func (t *GoHtmlTemplate) LoadTemplates(absPath string) {
-	t.loadTemplates(absPath, "")
-}
--- a/hugolib/template_embedded.go
+++ /dev/null
@@ -1,97 +1,0 @@
-// Copyright © 2013 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 hugolib
-
-type Tmpl struct {
-	Name string
-	Data string
-}
-
-func (t *GoHtmlTemplate) EmbedShortcodes() {
-	t.AddInternalShortcode("highlight.html", `{{ .Get 0 | highlight .Inner  }}`)
-	t.AddInternalShortcode("test.html", `This is a simple Test`)
-	t.AddInternalShortcode("figure.html", `<!-- image -->
-<figure {{ with .Get "class" }}class="{{.}}"{{ end }}>
-    {{ with .Get "link"}}<a href="{{.}}">{{ end }}
-        <img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt"}}{{.}}{{else}}{{ .Get "caption" }}{{ end }}" {{ end }}{{ with .Get "width" }}width="{{.}}" {{ end }}/>
-    {{ if .Get "link"}}</a>{{ end }}
-    {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
-    <figcaption>{{ if isset .Params "title" }}
-        <h4>{{ .Get "title" }}</h4>{{ end }}
-        {{ if or (.Get "caption") (.Get "attr")}}<p>
-        {{ .Get "caption" }}
-        {{ with .Get "attrlink"}}<a href="{{.}}"> {{ end }}
-            {{ .Get "attr" }}
-        {{ if .Get "attrlink"}}</a> {{ end }}
-        </p> {{ end }}
-    </figcaption>
-    {{ end }}
-</figure>
-<!-- image -->`)
-}
-
-func (t *GoHtmlTemplate) EmbedTemplates() {
-
-	t.AddInternalTemplate("_default", "rss.xml", `<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
-  <channel>
-    <title>{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}</title>
-    <link>{{ .Permalink }}</link>
-    <description>Recent content {{ with .Title }}in {{.}} {{ end }}on {{ .Site.Title }}</description>
-    <generator>Hugo -- gohugo.io</generator>
-    {{ with .Site.LanguageCode }}<language>{{.}}</language>{{end}}
-    {{ with .Site.Author.name }}<author>{{.}}</author>{{end}}
-    {{ with .Site.Copyright }}<copyright>{{.}}</copyright>{{end}}
-    <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 MST" }}</lastBuildDate>
-    <atom:link href="{{.Url}}" rel="self" type="application/rss+xml" />
-    {{ range first 15 .Data.Pages }}
-    <item>
-      <title>{{ .Title }}</title>
-      <link>{{ .Permalink }}</link>
-      <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 MST" }}</pubDate>
-      {{with .Site.Author.name}}<author>{{.}}</author>{{end}}
-      <guid>{{ .Permalink }}</guid>
-      <description>{{ .Content | html }}</description>
-    </item>
-    {{ end }}
-  </channel>
-</rss>`)
-
-	t.AddInternalTemplate("_default", "sitemap.xml", `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-  {{ range .Data.Pages }}
-  <url>
-    <loc>{{ .Permalink }}</loc>
-    <lastmod>{{ safeHtml ( .Date.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ with .Sitemap.ChangeFreq }}
-    <changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
-    <priority>{{ .Sitemap.Priority }}</priority>{{ end }}
-  </url>
-  {{ end }}
-</urlset>`)
-
-	t.AddInternalTemplate("", "disqus.html", `{{ if .Site.DisqusShortname }}<div id="disqus_thread"></div>
-<script type="text/javascript">
-    var disqus_shortname = '{{ .Site.DisqusShortname }}';
-    var disqus_identifier = '{{with .GetParam "disqus_identifier" }}{{ . }}{{ else }}{{ .Permalink }}{{end}}';
-    var disqus_title = '{{with .GetParam "disqus_title" }}{{ . }}{{ else }}{{ .Title }}{{end}}';
-    var disqus_url = '{{with .GetParam "disqus_url" }}{{ . | html  }}{{ else }}{{ .Permalink }}{{end}}';
-
-    (function() {
-        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
-        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
-        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
-    })();
-</script>
-<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
-<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>{{end}}`)
-
-}
--- a/hugolib/template_test.go
+++ /dev/null
@@ -1,342 +1,0 @@
-package hugolib
-
-import (
-	"github.com/spf13/hugo/source"
-	"reflect"
-	"testing"
-)
-
-func TestGt(t *testing.T) {
-	for i, this := range []struct {
-		left          interface{}
-		right         interface{}
-		leftShouldWin bool
-	}{
-		{5, 8, false},
-		{8, 5, true},
-		{5, 5, false},
-		{-2, 1, false},
-		{2, -5, true},
-		{0.0, 1.23, false},
-		{1.23, 0.0, true},
-		{"8", "5", true},
-		{"5", "0001", true},
-		{[]int{100, 99}, []int{1, 2, 3, 4}, false},
-	} {
-		leftIsBigger := Gt(this.left, this.right)
-		if leftIsBigger != this.leftShouldWin {
-			var which string
-			if leftIsBigger {
-				which = "expected right to be bigger, but left was"
-			} else {
-				which = "expected left to be bigger, but right was"
-			}
-			t.Errorf("[%d] %v compared to %v: %s", i, this.left, this.right, which)
-		}
-	}
-}
-
-func TestDoArithmetic(t *testing.T) {
-	for i, this := range []struct {
-		a      interface{}
-		b      interface{}
-		op     rune
-		expect interface{}
-	}{
-		{3, 2, '+', int64(5)},
-		{3, 2, '-', int64(1)},
-		{3, 2, '*', int64(6)},
-		{3, 2, '/', int64(1)},
-		{3.0, 2, '+', float64(5)},
-		{3.0, 2, '-', float64(1)},
-		{3.0, 2, '*', float64(6)},
-		{3.0, 2, '/', float64(1.5)},
-		{3, 2.0, '+', float64(5)},
-		{3, 2.0, '-', float64(1)},
-		{3, 2.0, '*', float64(6)},
-		{3, 2.0, '/', float64(1.5)},
-		{3.0, 2.0, '+', float64(5)},
-		{3.0, 2.0, '-', float64(1)},
-		{3.0, 2.0, '*', float64(6)},
-		{3.0, 2.0, '/', float64(1.5)},
-		{uint(3), uint(2), '+', uint64(5)},
-		{uint(3), uint(2), '-', uint64(1)},
-		{uint(3), uint(2), '*', uint64(6)},
-		{uint(3), uint(2), '/', uint64(1)},
-		{uint(3), 2, '+', uint64(5)},
-		{uint(3), 2, '-', uint64(1)},
-		{uint(3), 2, '*', uint64(6)},
-		{uint(3), 2, '/', uint64(1)},
-		{3, uint(2), '+', uint64(5)},
-		{3, uint(2), '-', uint64(1)},
-		{3, uint(2), '*', uint64(6)},
-		{3, uint(2), '/', uint64(1)},
-		{uint(3), -2, '+', int64(1)},
-		{uint(3), -2, '-', int64(5)},
-		{uint(3), -2, '*', int64(-6)},
-		{uint(3), -2, '/', int64(-1)},
-		{-3, uint(2), '+', int64(-1)},
-		{-3, uint(2), '-', int64(-5)},
-		{-3, uint(2), '*', int64(-6)},
-		{-3, uint(2), '/', int64(-1)},
-		{uint(3), 2.0, '+', float64(5)},
-		{uint(3), 2.0, '-', float64(1)},
-		{uint(3), 2.0, '*', float64(6)},
-		{uint(3), 2.0, '/', float64(1.5)},
-		{3.0, uint(2), '+', float64(5)},
-		{3.0, uint(2), '-', float64(1)},
-		{3.0, uint(2), '*', float64(6)},
-		{3.0, uint(2), '/', float64(1.5)},
-		{0, 0, '+', 0},
-		{0, 0, '-', 0},
-		{0, 0, '*', 0},
-		{"foo", "bar", '+', "foobar"},
-		{3, 0, '/', false},
-		{3.0, 0, '/', false},
-		{3, 0.0, '/', false},
-		{uint(3), uint(0), '/', false},
-		{3, uint(0), '/', false},
-		{-3, uint(0), '/', false},
-		{uint(3), 0, '/', false},
-		{3.0, uint(0), '/', false},
-		{uint(3), 0.0, '/', false},
-		{3, "foo", '+', false},
-		{3.0, "foo", '+', false},
-		{uint(3), "foo", '+', false},
-		{"foo", 3, '+', false},
-		{"foo", "bar", '-', false},
-		{3, 2, '%', false},
-	} {
-		result, err := doArithmetic(this.a, this.b, this.op)
-		if b, ok := this.expect.(bool); ok && !b {
-			if err == nil {
-				t.Errorf("[%d] doArithmetic didn't return an expected error")
-			}
-		} else {
-			if err != nil {
-				t.Errorf("[%d] failed: %s", i, err)
-				continue
-			}
-			if !reflect.DeepEqual(result, this.expect) {
-				t.Errorf("[%d] doArithmetic got %v but expected %v", i, result, 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")
-			}
-		} 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")
-			}
-		} 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},
-	} {
-		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")
-			}
-		} 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 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 (x *TstX) TstRp() string {
-	return "r" + x.A
-}
-
-func (x TstX) TstRv() string {
-	return "r" + x.B
-}
-
-type TstX struct {
-	A, B string
-}
-
-func TestWhere(t *testing.T) {
-
-	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")}}
-
-	for i, this := range []struct {
-		sequence interface{}
-		key      interface{}
-		match    interface{}
-		expect   interface{}
-	}{
-		{[]map[int]string{{1: "a", 2: "m"}, {1: "c", 2: "d"}, {1: "e", 3: "m"}}, 2, "m", []map[int]string{{1: "a", 2: "m"}}},
-		{[]map[string]int{{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4}}, "b", 4, []map[string]int{{"a": 3, "b": 4}}},
-		{[]TstX{{"a", "b"}, {"c", "d"}, {"e", "f"}}, "B", "f", []TstX{{"e", "f"}}},
-		{[]*map[int]string{&map[int]string{1: "a", 2: "m"}, &map[int]string{1: "c", 2: "d"}, &map[int]string{1: "e", 3: "m"}}, 2, "m", []*map[int]string{&map[int]string{1: "a", 2: "m"}}},
-		{[]*TstX{&TstX{"a", "b"}, &TstX{"c", "d"}, &TstX{"e", "f"}}, "B", "f", []*TstX{&TstX{"e", "f"}}},
-		{[]*TstX{&TstX{"a", "b"}, &TstX{"c", "d"}, &TstX{"e", "c"}}, "TstRp", "rc", []*TstX{&TstX{"c", "d"}}},
-		{[]TstX{TstX{"a", "b"}, TstX{"c", "d"}, TstX{"e", "c"}}, "TstRv", "rc", []TstX{TstX{"e", "c"}}},
-		{[]*Page{page1, page2}, "Type", "v", []*Page{page1}},
-		{[]*Page{page1, page2}, "Section", "y", []*Page{page2}},
-	} {
-		results, err := Where(this.sequence, this.key, this.match)
-		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)
-		}
-	}
-}
--- /dev/null
+++ b/tpl/template.go
@@ -1,0 +1,714 @@
+// 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"
+	"html"
+	"html/template"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"reflect"
+	"strconv"
+	"strings"
+
+	"github.com/eknkc/amber"
+	"github.com/spf13/cast"
+	"github.com/spf13/hugo/helpers"
+	jww "github.com/spf13/jwalterweatherman"
+)
+
+var localTemplates *template.Template
+var tmpl Template
+
+type Template interface {
+	ExecuteTemplate(wr io.Writer, name string, data interface{}) error
+	Lookup(name string) *template.Template
+	Templates() []*template.Template
+	New(name string) *template.Template
+	LoadTemplates(absPath string)
+	LoadTemplatesWithPrefix(absPath, prefix string)
+	AddTemplate(name, tpl string) error
+	AddInternalTemplate(prefix, name, tpl string) error
+	AddInternalShortcode(name, tpl string) error
+}
+
+type templateErr struct {
+	name string
+	err  error
+}
+
+type GoHtmlTemplate struct {
+	template.Template
+	errors []*templateErr
+}
+
+// The "Global" Template System
+func T() Template {
+	if tmpl == nil {
+		tmpl = New()
+	}
+
+	return tmpl
+}
+
+// Return a new Hugo Template System
+// With all the additional features, templates & functions
+func New() Template {
+	var templates = &GoHtmlTemplate{
+		Template: *template.New(""),
+		errors:   make([]*templateErr, 0),
+	}
+
+	localTemplates = &templates.Template
+
+	funcMap := template.FuncMap{
+		"urlize":      helpers.Urlize,
+		"sanitizeurl": helpers.SanitizeUrl,
+		"eq":          Eq,
+		"ne":          Ne,
+		"gt":          Gt,
+		"ge":          Ge,
+		"lt":          Lt,
+		"le":          Le,
+		"in":          In,
+		"intersect":   Intersect,
+		"isset":       IsSet,
+		"echoParam":   ReturnWhenSet,
+		"safeHtml":    SafeHtml,
+		"first":       First,
+		"where":       Where,
+		"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,
+	}
+
+	templates.Funcs(funcMap)
+	templates.LoadEmbedded()
+	return templates
+}
+
+func Eq(x, y interface{}) bool {
+	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
+	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, _ = strconv.ParseFloat(av.String(), 64)
+	}
+
+	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, _ = strconv.ParseFloat(bv.String(), 64)
+	}
+
+	return left, right
+}
+
+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
+}
+
+// First is exposed to templates, to iterate over the first N items in a
+// rangeable list.
+func First(limit interface{}, seq interface{}) (interface{}, error) {
+
+	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)
+	// this is better than my first pass; ripped from text/template/exec.go indirect():
+	for ; seqv.Kind() == reflect.Ptr || seqv.Kind() == reflect.Interface; seqv = seqv.Elem() {
+		if seqv.IsNil() {
+			return nil, errors.New("can't iterate over a nil value")
+		}
+		if seqv.Kind() == reflect.Interface && seqv.NumMethod() > 0 {
+			break
+		}
+	}
+
+	switch seqv.Kind() {
+	case reflect.Array, reflect.Slice, reflect.String:
+		// okay
+	default:
+		return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
+	}
+	if limitv > seqv.Len() {
+		limitv = seqv.Len()
+	}
+	return seqv.Slice(0, limitv).Interface(), nil
+}
+
+func Where(seq, key, match interface{}) (interface{}, error) {
+	seqv := reflect.ValueOf(seq)
+	kv := reflect.ValueOf(key)
+	mv := reflect.ValueOf(match)
+
+	// this is better than my first pass; ripped from text/template/exec.go indirect():
+	for ; seqv.Kind() == reflect.Ptr || seqv.Kind() == reflect.Interface; seqv = seqv.Elem() {
+		if seqv.IsNil() {
+			return nil, errors.New("can't iterate over a nil value")
+		}
+		if seqv.Kind() == reflect.Interface && seqv.NumMethod() > 0 {
+			break
+		}
+	}
+
+	switch seqv.Kind() {
+	case reflect.Array, reflect.Slice:
+		r := reflect.MakeSlice(seqv.Type(), 0, 0)
+		for i := 0; i < seqv.Len(); i++ {
+			var vvv reflect.Value
+			vv := seqv.Index(i)
+			switch vv.Kind() {
+			case reflect.Map:
+				if kv.Type() == vv.Type().Key() && vv.MapIndex(kv).IsValid() {
+					vvv = vv.MapIndex(kv)
+				}
+			case reflect.Struct:
+				if kv.Kind() == reflect.String {
+					method := vv.MethodByName(kv.String())
+					if method.IsValid() && method.Type().NumIn() == 0 && method.Type().NumOut() > 0 {
+						vvv = method.Call(nil)[0]
+					} else if vv.FieldByName(kv.String()).IsValid() {
+						vvv = vv.FieldByName(kv.String())
+					}
+				}
+			case reflect.Ptr:
+				if !vv.IsNil() {
+					ev := vv.Elem()
+					switch ev.Kind() {
+					case reflect.Map:
+						if kv.Type() == ev.Type().Key() && ev.MapIndex(kv).IsValid() {
+							vvv = ev.MapIndex(kv)
+						}
+					case reflect.Struct:
+						if kv.Kind() == reflect.String {
+							method := vv.MethodByName(kv.String())
+							if method.IsValid() && method.Type().NumIn() == 0 && method.Type().NumOut() > 0 {
+								vvv = method.Call(nil)[0]
+							} else if ev.FieldByName(kv.String()).IsValid() {
+								vvv = ev.FieldByName(kv.String())
+							}
+						}
+					}
+				}
+			}
+
+			if vvv.IsValid() && mv.Type() == vvv.Type() {
+				switch mv.Kind() {
+				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+					if mv.Int() == vvv.Int() {
+						r = reflect.Append(r, vv)
+					}
+				case reflect.String:
+					if mv.String() == vvv.String() {
+						r = reflect.Append(r, vv)
+					}
+				}
+			}
+		}
+		return r.Interface(), nil
+	default:
+		return nil, errors.New("can't iterate over " + reflect.ValueOf(seq).Type().String())
+	}
+}
+
+func IsSet(a interface{}, key interface{}) bool {
+	av := reflect.ValueOf(a)
+	kv := reflect.ValueOf(key)
+
+	switch av.Kind() {
+	case reflect.Array, reflect.Chan, reflect.Slice:
+		if int64(av.Len()) > kv.Int() {
+			return true
+		}
+	case reflect.Map:
+		if kv.Type() == av.Type().Key() {
+			return av.MapIndex(kv).IsValid()
+		}
+	}
+
+	return false
+}
+
+func ReturnWhenSet(a interface{}, index int) interface{} {
+	av := reflect.ValueOf(a)
+
+	switch av.Kind() {
+	case reflect.Array, reflect.Slice:
+		if av.Len() > index {
+
+			avv := av.Index(index)
+			switch avv.Kind() {
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				return avv.Int()
+			case reflect.String:
+				return avv.String()
+			}
+		}
+	}
+
+	return ""
+}
+
+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))
+}
+
+func SafeHtml(text string) template.HTML {
+	return template.HTML(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:]
+	}
+	var context interface{}
+
+	if len(context_list) == 0 {
+		context = nil
+	} else {
+		context = context_list[0]
+	}
+	return ExecuteTemplateToHTML(context, "partials/"+name, "theme/partials/"+name)
+}
+
+func ExecuteTemplate(context interface{}, layouts ...string) *bytes.Buffer {
+	buffer := new(bytes.Buffer)
+	worked := false
+	for _, layout := range layouts {
+		name := layout
+
+		if localTemplates.Lookup(name) == nil {
+			name = layout + ".html"
+		}
+
+		if localTemplates.Lookup(name) != nil {
+			err := localTemplates.ExecuteTemplate(buffer, name, context)
+			if err != nil {
+				jww.ERROR.Println(err, "in", name)
+			}
+			worked = true
+			break
+		}
+	}
+	if !worked {
+		jww.ERROR.Println("Unable to render", layouts)
+		jww.ERROR.Println("Expecting to find a template in either the theme/layouts or /layouts in one of the following relative locations", layouts)
+	}
+
+	return buffer
+}
+
+func ExecuteTemplateToHTML(context interface{}, layouts ...string) template.HTML {
+	b := ExecuteTemplate(context, layouts...)
+	return template.HTML(string(b.Bytes()))
+}
+
+func (t *GoHtmlTemplate) LoadEmbedded() {
+	t.EmbedShortcodes()
+	t.EmbedTemplates()
+}
+
+func (t *GoHtmlTemplate) AddInternalTemplate(prefix, name, tpl string) error {
+	if prefix != "" {
+		return t.AddTemplate("_internal/"+prefix+"/"+name, tpl)
+	} else {
+		return t.AddTemplate("_internal/"+name, tpl)
+	}
+}
+
+func (t *GoHtmlTemplate) AddInternalShortcode(name, content string) error {
+	return t.AddInternalTemplate("shortcodes", name, content)
+}
+
+func (t *GoHtmlTemplate) AddTemplate(name, tpl string) error {
+	_, err := t.New(name).Parse(tpl)
+	if err != nil {
+		t.errors = append(t.errors, &templateErr{name: name, err: err})
+	}
+	return err
+}
+
+func (t *GoHtmlTemplate) AddTemplateFile(name, path string) error {
+	// get the suffix and switch on that
+	ext := filepath.Ext(path)
+	switch ext {
+	case ".amber":
+		compiler := amber.New()
+		// Parse the input file
+		if err := compiler.ParseFile(path); err != nil {
+			return nil
+		}
+
+		if _, err := compiler.CompileWithTemplate(t.New(name)); err != nil {
+			return err
+		}
+	default:
+		b, err := ioutil.ReadFile(path)
+		if err != nil {
+			return err
+		}
+
+		return t.AddTemplate(name, string(b))
+	}
+
+	return nil
+
+}
+
+func (t *GoHtmlTemplate) generateTemplateNameFrom(base, path string) string {
+	return filepath.ToSlash(path[len(base)+1:])
+}
+
+func ignoreDotFile(path string) bool {
+	return filepath.Base(path)[0] == '.'
+}
+
+func (t *GoHtmlTemplate) loadTemplates(absPath string, prefix string) {
+	walker := func(path string, fi os.FileInfo, err error) error {
+		if err != nil {
+			return nil
+		}
+
+		if !fi.IsDir() {
+			if ignoreDotFile(path) {
+				return nil
+			}
+
+			tplName := t.generateTemplateNameFrom(absPath, path)
+
+			if prefix != "" {
+				tplName = strings.Trim(prefix, "/") + "/" + tplName
+			}
+
+			t.AddTemplateFile(tplName, path)
+
+		}
+		return nil
+	}
+
+	filepath.Walk(absPath, walker)
+}
+
+func (t *GoHtmlTemplate) LoadTemplatesWithPrefix(absPath string, prefix string) {
+	t.loadTemplates(absPath, prefix)
+}
+
+func (t *GoHtmlTemplate) LoadTemplates(absPath string) {
+	t.loadTemplates(absPath, "")
+}
--- /dev/null
+++ b/tpl/template_embedded.go
@@ -1,0 +1,97 @@
+// Copyright © 2013 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
+
+type Tmpl struct {
+	Name string
+	Data string
+}
+
+func (t *GoHtmlTemplate) EmbedShortcodes() {
+	t.AddInternalShortcode("highlight.html", `{{ .Get 0 | highlight .Inner  }}`)
+	t.AddInternalShortcode("test.html", `This is a simple Test`)
+	t.AddInternalShortcode("figure.html", `<!-- image -->
+<figure {{ with .Get "class" }}class="{{.}}"{{ end }}>
+    {{ with .Get "link"}}<a href="{{.}}">{{ end }}
+        <img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt"}}{{.}}{{else}}{{ .Get "caption" }}{{ end }}" {{ end }}{{ with .Get "width" }}width="{{.}}" {{ end }}/>
+    {{ if .Get "link"}}</a>{{ end }}
+    {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
+    <figcaption>{{ if isset .Params "title" }}
+        <h4>{{ .Get "title" }}</h4>{{ end }}
+        {{ if or (.Get "caption") (.Get "attr")}}<p>
+        {{ .Get "caption" }}
+        {{ with .Get "attrlink"}}<a href="{{.}}"> {{ end }}
+            {{ .Get "attr" }}
+        {{ if .Get "attrlink"}}</a> {{ end }}
+        </p> {{ end }}
+    </figcaption>
+    {{ end }}
+</figure>
+<!-- image -->`)
+}
+
+func (t *GoHtmlTemplate) EmbedTemplates() {
+
+	t.AddInternalTemplate("_default", "rss.xml", `<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+  <channel>
+    <title>{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}</title>
+    <link>{{ .Permalink }}</link>
+    <description>Recent content {{ with .Title }}in {{.}} {{ end }}on {{ .Site.Title }}</description>
+    <generator>Hugo -- gohugo.io</generator>
+    {{ with .Site.LanguageCode }}<language>{{.}}</language>{{end}}
+    {{ with .Site.Author.name }}<author>{{.}}</author>{{end}}
+    {{ with .Site.Copyright }}<copyright>{{.}}</copyright>{{end}}
+    <lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 MST" }}</lastBuildDate>
+    <atom:link href="{{.Url}}" rel="self" type="application/rss+xml" />
+    {{ range first 15 .Data.Pages }}
+    <item>
+      <title>{{ .Title }}</title>
+      <link>{{ .Permalink }}</link>
+      <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 MST" }}</pubDate>
+      {{with .Site.Author.name}}<author>{{.}}</author>{{end}}
+      <guid>{{ .Permalink }}</guid>
+      <description>{{ .Content | html }}</description>
+    </item>
+    {{ end }}
+  </channel>
+</rss>`)
+
+	t.AddInternalTemplate("_default", "sitemap.xml", `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+  {{ range .Data.Pages }}
+  <url>
+    <loc>{{ .Permalink }}</loc>
+    <lastmod>{{ safeHtml ( .Date.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ with .Sitemap.ChangeFreq }}
+    <changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
+    <priority>{{ .Sitemap.Priority }}</priority>{{ end }}
+  </url>
+  {{ end }}
+</urlset>`)
+
+	t.AddInternalTemplate("", "disqus.html", `{{ if .Site.DisqusShortname }}<div id="disqus_thread"></div>
+<script type="text/javascript">
+    var disqus_shortname = '{{ .Site.DisqusShortname }}';
+    var disqus_identifier = '{{with .GetParam "disqus_identifier" }}{{ . }}{{ else }}{{ .Permalink }}{{end}}';
+    var disqus_title = '{{with .GetParam "disqus_title" }}{{ . }}{{ else }}{{ .Title }}{{end}}';
+    var disqus_url = '{{with .GetParam "disqus_url" }}{{ . | html  }}{{ else }}{{ .Permalink }}{{end}}';
+
+    (function() {
+        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
+        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
+        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
+    })();
+</script>
+<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
+<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>{{end}}`)
+
+}
--- /dev/null
+++ b/tpl/template_test.go
@@ -1,0 +1,341 @@
+package tpl
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestGt(t *testing.T) {
+	for i, this := range []struct {
+		left          interface{}
+		right         interface{}
+		leftShouldWin bool
+	}{
+		{5, 8, false},
+		{8, 5, true},
+		{5, 5, false},
+		{-2, 1, false},
+		{2, -5, true},
+		{0.0, 1.23, false},
+		{1.23, 0.0, true},
+		{"8", "5", true},
+		{"5", "0001", true},
+		{[]int{100, 99}, []int{1, 2, 3, 4}, false},
+	} {
+		leftIsBigger := Gt(this.left, this.right)
+		if leftIsBigger != this.leftShouldWin {
+			var which string
+			if leftIsBigger {
+				which = "expected right to be bigger, but left was"
+			} else {
+				which = "expected left to be bigger, but right was"
+			}
+			t.Errorf("[%d] %v compared to %v: %s", i, this.left, this.right, which)
+		}
+	}
+}
+
+func TestDoArithmetic(t *testing.T) {
+	for i, this := range []struct {
+		a      interface{}
+		b      interface{}
+		op     rune
+		expect interface{}
+	}{
+		{3, 2, '+', int64(5)},
+		{3, 2, '-', int64(1)},
+		{3, 2, '*', int64(6)},
+		{3, 2, '/', int64(1)},
+		{3.0, 2, '+', float64(5)},
+		{3.0, 2, '-', float64(1)},
+		{3.0, 2, '*', float64(6)},
+		{3.0, 2, '/', float64(1.5)},
+		{3, 2.0, '+', float64(5)},
+		{3, 2.0, '-', float64(1)},
+		{3, 2.0, '*', float64(6)},
+		{3, 2.0, '/', float64(1.5)},
+		{3.0, 2.0, '+', float64(5)},
+		{3.0, 2.0, '-', float64(1)},
+		{3.0, 2.0, '*', float64(6)},
+		{3.0, 2.0, '/', float64(1.5)},
+		{uint(3), uint(2), '+', uint64(5)},
+		{uint(3), uint(2), '-', uint64(1)},
+		{uint(3), uint(2), '*', uint64(6)},
+		{uint(3), uint(2), '/', uint64(1)},
+		{uint(3), 2, '+', uint64(5)},
+		{uint(3), 2, '-', uint64(1)},
+		{uint(3), 2, '*', uint64(6)},
+		{uint(3), 2, '/', uint64(1)},
+		{3, uint(2), '+', uint64(5)},
+		{3, uint(2), '-', uint64(1)},
+		{3, uint(2), '*', uint64(6)},
+		{3, uint(2), '/', uint64(1)},
+		{uint(3), -2, '+', int64(1)},
+		{uint(3), -2, '-', int64(5)},
+		{uint(3), -2, '*', int64(-6)},
+		{uint(3), -2, '/', int64(-1)},
+		{-3, uint(2), '+', int64(-1)},
+		{-3, uint(2), '-', int64(-5)},
+		{-3, uint(2), '*', int64(-6)},
+		{-3, uint(2), '/', int64(-1)},
+		{uint(3), 2.0, '+', float64(5)},
+		{uint(3), 2.0, '-', float64(1)},
+		{uint(3), 2.0, '*', float64(6)},
+		{uint(3), 2.0, '/', float64(1.5)},
+		{3.0, uint(2), '+', float64(5)},
+		{3.0, uint(2), '-', float64(1)},
+		{3.0, uint(2), '*', float64(6)},
+		{3.0, uint(2), '/', float64(1.5)},
+		{0, 0, '+', 0},
+		{0, 0, '-', 0},
+		{0, 0, '*', 0},
+		{"foo", "bar", '+', "foobar"},
+		{3, 0, '/', false},
+		{3.0, 0, '/', false},
+		{3, 0.0, '/', false},
+		{uint(3), uint(0), '/', false},
+		{3, uint(0), '/', false},
+		{-3, uint(0), '/', false},
+		{uint(3), 0, '/', false},
+		{3.0, uint(0), '/', false},
+		{uint(3), 0.0, '/', false},
+		{3, "foo", '+', false},
+		{3.0, "foo", '+', false},
+		{uint(3), "foo", '+', false},
+		{"foo", 3, '+', false},
+		{"foo", "bar", '-', false},
+		{3, 2, '%', false},
+	} {
+		result, err := doArithmetic(this.a, this.b, this.op)
+		if b, ok := this.expect.(bool); ok && !b {
+			if err == nil {
+				t.Errorf("[%d] doArithmetic didn't return an expected error")
+			}
+		} else {
+			if err != nil {
+				t.Errorf("[%d] failed: %s", i, err)
+				continue
+			}
+			if !reflect.DeepEqual(result, this.expect) {
+				t.Errorf("[%d] doArithmetic got %v but expected %v", i, result, 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")
+			}
+		} 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")
+			}
+		} 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},
+	} {
+		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")
+			}
+		} 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 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 (x *TstX) TstRp() string {
+	return "r" + x.A
+}
+
+func (x TstX) TstRv() string {
+	return "r" + x.B
+}
+
+type TstX struct {
+	A, B string
+}
+
+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")}}
+
+	for i, this := range []struct {
+		sequence interface{}
+		key      interface{}
+		match    interface{}
+		expect   interface{}
+	}{
+		{[]map[int]string{{1: "a", 2: "m"}, {1: "c", 2: "d"}, {1: "e", 3: "m"}}, 2, "m", []map[int]string{{1: "a", 2: "m"}}},
+		{[]map[string]int{{"a": 1, "b": 2}, {"a": 3, "b": 4}, {"a": 5, "x": 4}}, "b", 4, []map[string]int{{"a": 3, "b": 4}}},
+		{[]TstX{{"a", "b"}, {"c", "d"}, {"e", "f"}}, "B", "f", []TstX{{"e", "f"}}},
+		{[]*map[int]string{&map[int]string{1: "a", 2: "m"}, &map[int]string{1: "c", 2: "d"}, &map[int]string{1: "e", 3: "m"}}, 2, "m", []*map[int]string{&map[int]string{1: "a", 2: "m"}}},
+		{[]*TstX{&TstX{"a", "b"}, &TstX{"c", "d"}, &TstX{"e", "f"}}, "B", "f", []*TstX{&TstX{"e", "f"}}},
+		{[]*TstX{&TstX{"a", "b"}, &TstX{"c", "d"}, &TstX{"e", "c"}}, "TstRp", "rc", []*TstX{&TstX{"c", "d"}}},
+		{[]TstX{TstX{"a", "b"}, TstX{"c", "d"}, TstX{"e", "c"}}, "TstRv", "rc", []TstX{TstX{"e", "c"}}},
+		//{[]*Page{page1, page2}, "Type", "v", []*Page{page1}},
+		//{[]*Page{page1, page2}, "Section", "y", []*Page{page2}},
+	} {
+		results, err := Where(this.sequence, this.key, this.match)
+		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)
+		}
+	}
+}