mirror of
https://github.com/gohugoio/hugo.git
synced 2025-05-06 07:33:16 +00: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.
|
`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`
|
## 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
|
// Dictionary creates a map[string]interface{} from the given parameters by
|
||||||
// walking the parameters and treating them as key-value pairs. The number
|
// walking the parameters and treating them as key-value pairs. The number
|
||||||
// of parameters must be even.
|
// 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) {
|
func (ns *Namespace) Dictionary(values ...interface{}) (map[string]interface{}, error) {
|
||||||
if len(values)%2 != 0 {
|
if len(values)%2 != 0 {
|
||||||
return nil, errors.New("invalid dictionary call")
|
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 {
|
for i := 0; i < len(values); i += 2 {
|
||||||
key, ok := values[i].(string)
|
dict := root
|
||||||
if !ok {
|
var key string
|
||||||
return nil, errors.New("dictionary keys must be strings")
|
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]
|
dict[key] = values[i+1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return dict, nil
|
return root, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EchoParam returns a given value if it is set; otherwise, it returns an
|
// 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) {
|
func TestDictionary(t *testing.T) {
|
||||||
t.Parallel()
|
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{})
|
||||||
|
@ -192,22 +191,30 @@ func TestDictionary(t *testing.T) {
|
||||||
expect interface{}
|
expect interface{}
|
||||||
}{
|
}{
|
||||||
{[]interface{}{"a", "b"}, map[string]interface{}{"a": "b"}},
|
{[]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}}},
|
{[]interface{}{"a", 12, "b", []int{4}}, map[string]interface{}{"a": 12, "b": []int{4}}},
|
||||||
// errors
|
// errors
|
||||||
{[]interface{}{5, "b"}, false},
|
{[]interface{}{5, "b"}, false},
|
||||||
{[]interface{}{"a", "b", "c"}, 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 {
|
if b, ok := test.expect.(bool); ok && !b {
|
||||||
c.Assert(err, qt.Not(qt.IsNil), errMsg)
|
c.Assert(err, qt.Not(qt.IsNil), errMsg)
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Assert(err, qt.IsNil, errMsg)
|
c.Assert(err, qt.IsNil, errMsg)
|
||||||
c.Assert(result, qt.DeepEquals, test.expect, errMsg)
|
c.Assert(result, qt.DeepEquals, test.expect, qt.Commentf(fmt.Sprint(result)))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue