mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
parent
1a36ce9b09
commit
a2670bf460
3 changed files with 46 additions and 14 deletions
|
@ -21,6 +21,12 @@ aliases: []
|
|||
|
||||
`dict` is especially useful for passing more than one value to a partial template.
|
||||
|
||||
Note that the `key` can be either a `string` or a `string slice`. The latter is useful to create a deply nested structure, e.g.:
|
||||
|
||||
```go-text-template
|
||||
{{ $m := dict (slice "a" "b" "c") "value" }}
|
||||
```
|
||||
|
||||
|
||||
## Example: Using `dict` to pass multiple values to a `partial`
|
||||
|
||||
|
|
|
@ -145,22 +145,41 @@ func (ns *Namespace) Delimit(seq, delimiter interface{}, last ...interface{}) (t
|
|||
// Dictionary creates a map[string]interface{} from the given parameters by
|
||||
// walking the parameters and treating them as key-value pairs. The number
|
||||
// of parameters must be even.
|
||||
// The keys can be string slices, which will create the needed nested structure.
|
||||
func (ns *Namespace) Dictionary(values ...interface{}) (map[string]interface{}, error) {
|
||||
if len(values)%2 != 0 {
|
||||
return nil, errors.New("invalid dictionary call")
|
||||
}
|
||||
|
||||
dict := make(map[string]interface{}, len(values)/2)
|
||||
root := make(map[string]interface{})
|
||||
|
||||
for i := 0; i < len(values); i += 2 {
|
||||
key, ok := values[i].(string)
|
||||
if !ok {
|
||||
return nil, errors.New("dictionary keys must be strings")
|
||||
dict := root
|
||||
var key string
|
||||
switch v := values[i].(type) {
|
||||
case string:
|
||||
key = v
|
||||
case []string:
|
||||
for i := 0; i < len(v)-1; i++ {
|
||||
key = v[i]
|
||||
var m map[string]interface{}
|
||||
v, found := dict[key]
|
||||
if found {
|
||||
m = v.(map[string]interface{})
|
||||
} else {
|
||||
m = make(map[string]interface{})
|
||||
dict[key] = m
|
||||
}
|
||||
dict = m
|
||||
}
|
||||
key = v[len(v)-1]
|
||||
default:
|
||||
return nil, errors.New("invalid dictionary key")
|
||||
}
|
||||
dict[key] = values[i+1]
|
||||
}
|
||||
|
||||
return dict, nil
|
||||
return root, nil
|
||||
}
|
||||
|
||||
// EchoParam returns a given value if it is set; otherwise, it returns an
|
||||
|
|
|
@ -182,7 +182,6 @@ func TestDelimit(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDictionary(t *testing.T) {
|
||||
t.Parallel()
|
||||
c := qt.New(t)
|
||||
|
||||
ns := New(&deps.Deps{})
|
||||
|
@ -192,22 +191,30 @@ func TestDictionary(t *testing.T) {
|
|||
expect interface{}
|
||||
}{
|
||||
{[]interface{}{"a", "b"}, map[string]interface{}{"a": "b"}},
|
||||
{[]interface{}{[]string{"a", "b"}, "c"}, map[string]interface{}{"a": map[string]interface{}{"b": "c"}}},
|
||||
{[]interface{}{[]string{"a", "b"}, "c", []string{"a", "b2"}, "c2", "b", "c"},
|
||||
map[string]interface{}{"a": map[string]interface{}{"b": "c", "b2": "c2"}, "b": "c"}},
|
||||
{[]interface{}{"a", 12, "b", []int{4}}, map[string]interface{}{"a": 12, "b": []int{4}}},
|
||||
// errors
|
||||
{[]interface{}{5, "b"}, false},
|
||||
{[]interface{}{"a", "b", "c"}, false},
|
||||
} {
|
||||
errMsg := qt.Commentf("[%d] %v", i, test.values)
|
||||
i := i
|
||||
test := test
|
||||
c.Run(fmt.Sprint(i), func(c *qt.C) {
|
||||
c.Parallel()
|
||||
errMsg := qt.Commentf("[%d] %v", i, test.values)
|
||||
|
||||
result, err := ns.Dictionary(test.values...)
|
||||
result, err := ns.Dictionary(test.values...)
|
||||
|
||||
if b, ok := test.expect.(bool); ok && !b {
|
||||
c.Assert(err, qt.Not(qt.IsNil), errMsg)
|
||||
continue
|
||||
}
|
||||
if b, ok := test.expect.(bool); ok && !b {
|
||||
c.Assert(err, qt.Not(qt.IsNil), errMsg)
|
||||
return
|
||||
}
|
||||
|
||||
c.Assert(err, qt.IsNil, errMsg)
|
||||
c.Assert(result, qt.DeepEquals, test.expect, errMsg)
|
||||
c.Assert(err, qt.IsNil, errMsg)
|
||||
c.Assert(result, qt.DeepEquals, test.expect, qt.Commentf(fmt.Sprint(result)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue