shithub: hugo

Download patch

ref: 13b067b5064cc1c59ade383612906fce944dcf33
parent: f78e2cb854a639789fdac37a19f895435a18a938
author: spf13 <[email protected]>
date: Thu Jan 9 12:27:39 EST 2014

Adding support for embedded templates

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