shithub: hugo

Download patch

ref: 04817c7b83e4b555ee22e21dadc0b8ddaf6423a0
parent: 9cc3d67c577377af1af1b9de594f99d9dabc05b3
author: Xin Fan <[email protected]>
date: Fri Mar 20 09:44:53 EDT 2015

Add Substr and Split template functions

Both of these can take any type the cast lib can turn into a string.

--- a/tpl/template.go
+++ b/tpl/template.go
@@ -188,6 +188,22 @@
 	return left, right
 }
 
+func Substr(a interface{}, pos, length int) (string, error) {
+	aStr, err := cast.ToStringE(a)
+	if err != nil {
+		return "", err
+	}
+	return aStr[pos:length], 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
@@ -1308,6 +1324,8 @@
 		"lt":          Lt,
 		"le":          Le,
 		"in":          In,
+		"substr":      Substr,
+		"split":       Split,
 		"intersect":   Intersect,
 		"isSet":       IsSet,
 		"isset":       IsSet,
--- a/tpl/template_test.go
+++ b/tpl/template_test.go
@@ -276,6 +276,63 @@
 	}
 }
 
+func TestSubstr(t *testing.T) {
+	for i, this := range []struct {
+		v1 interface{}
+		v2 int
+		v3 int
+		expect string
+	}{
+		{"abc", 1, 2, "b"},
+		{"abc", 1, 3, "bc"},
+		{"abc", 0, 1, "a"},
+	} {
+		result, err := Substr(this.v1, this.v2, this.v3)
+
+		if err != nil {
+			t.Errorf("[%d] failed: %s", i, err)
+			continue
+		}
+
+		if result != this.expect {
+			t.Errorf("[%d] Got %v but expected %v", i, result, this.expect)
+		}
+	}
+
+	_, err := Substr(tstNoStringer{}, 0, 1)
+	if err == nil {
+		t.Error("Expected error for non-string-convertable variable")
+	}
+}
+
+func TestSplit(t *testing.T) {
+	for i, this := range []struct {
+		v1 interface{}
+		v2 string
+		expect []string
+	}{
+		{"a, b", ", ", []string{"a", "b"}},
+		{"a & b & c", " & ", []string{"a", "b", "c"}},
+		{"http://exmaple.com", "http://", []string{"", "exmaple.com"}},
+	} {
+		result, err := Split(this.v1, this.v2)
+
+		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)
+		}
+	}
+
+	_, err := Split(tstNoStringer{}, ",")
+	if err == nil {
+		t.Error("Expected error for non-string-convertable variable")
+	}
+}
+
 func TestIntersect(t *testing.T) {
 	for i, this := range []struct {
 		sequence1 interface{}