ref: 3a27cefec1beb8e2e49ec206264d7d19cde0ffae
parent: ccd83c3040771ea496d41b63fa8cba2cecd46f0f
author: NotZippy <[email protected]>
date: Fri Oct 2 04:30:21 EDT 2015
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.
--- a/docs/content/templates/functions.md
+++ b/docs/content/templates/functions.md
@@ -50,6 +50,29 @@
// Outputs Tags: tag1, tag2 and tag3
+### dict
+Creates a dictionary (map[string, interface{}), expects parameters added in value:object fasion.
+Invalid combinations like keys that are not strings or uneven number of parameters, will result in an exception thrown
+Useful for passing maps to partials when adding to a template.
+
+e.g. Pass into "foo.html" a map with the keys "important, content"
+
+ {{$important := .Site.Params.SomethingImportant }}
+ {{range .Site.Params.Bar}}
+ {{partial "foo" (dict "content" . "important" $important)}}
+ {{end}}
+
+"foo.html"
+
+ Important {{.important}}
+ {{.content}}
+
+
+or Create a map on the fly to pass into
+
+ {{partial "foo" (dict "important" "Smiles" "content" "You should do more")}}
+
+
### echoParam
Prints a parameter if it is set.
--- a/tpl/template_funcs.go
+++ b/tpl/template_funcs.go
@@ -78,6 +78,21 @@
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 @@
"ge": Ge,
"lt": Lt,
"le": Le,
+ "dict": Dictionary,
"in": In,
"slicestr": Slicestr,
"substr": Substr,
--- a/tpl/template_funcs_test.go
+++ b/tpl/template_funcs_test.go
@@ -324,6 +324,30 @@
}
}
+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{}