Add dictionary function to be passed into a template

Allows templates to dynamically build maps.

Example usage: Creating and passing a map to a subtemplate while in a range on the parent.
This commit is contained in:
NotZippy
2015-10-02 08:30:21 -07:00
committed by Bjørn Erik Pedersen
parent ccd83c3040
commit 3a27cefec1
3 changed files with 63 additions and 0 deletions

View File

@@ -78,6 +78,21 @@ func Lt(a, b interface{}) bool {
return left < right
}
func Dictionary(values ...interface{}) (map[string]interface{}, error) {
if len(values)%2 != 0 {
return nil, errors.New("invalid dict call")
}
dict := make(map[string]interface{}, len(values)/2)
for i := 0; i < len(values); i+=2 {
key, ok := values[i].(string)
if !ok {
return nil, errors.New("dict keys must be strings")
}
dict[key] = values[i+1]
}
return dict, nil
}
func compareGetFloat(a interface{}, b interface{}) (float64, float64) {
var left, right float64
var leftStr, rightStr *string
@@ -1356,6 +1371,7 @@ func init() {
"ge": Ge,
"lt": Lt,
"le": Le,
"dict": Dictionary,
"in": In,
"slicestr": Slicestr,
"substr": Substr,

View File

@@ -324,6 +324,30 @@ func TestAfter(t *testing.T) {
}
}
func TestDictionary(t *testing.T) {
for i, this := range []struct {
v1 []interface{}
expecterr bool
expectedValue map[string] interface{}
}{
{[]interface{}{"a", "b"}, false, map[string]interface{}{"a":"b"}},
{[]interface{}{5, "b"}, true,nil},
{[]interface{}{"a", 12,"b",[]int{4}}, false,map[string]interface{}{"a":12,"b":[]int{4}}},
{[]interface{}{"a", "b", "c"}, true,nil},
} {
r,e := Dictionary(this.v1...)
if (this.expecterr && e==nil) || (!this.expecterr && e!=nil) {
t.Errorf("[%d] got an unexpected error", i, e, this.expecterr)
} else if !this.expecterr {
if !reflect.DeepEqual(r, this.expectedValue) {
t.Errorf("[%d] got %v but expected %v", i, r, this.expectedValue)
}
}
}
}
func TestIn(t *testing.T) {
for i, this := range []struct {
v1 interface{}