hugolib: Enhance .Param to permit arbitrarily nested parameter references

The Param method currently assumes that its argument is a single,
distinct, top-level key to look up in the Params map. This enhances the
Param method; it will now also attempt to see if the key can be
interpreted as a nested chain of keys to look up in Params.

Fixes #2598
This commit is contained in:
John Feminella
2017-02-19 02:50:08 -05:00
committed by Bjørn Erik Pedersen
parent 6d2281c8ea
commit b2e3748a4e
6 changed files with 142 additions and 11 deletions

View File

@@ -314,13 +314,64 @@ func (p *Page) Param(key interface{}) (interface{}, error) {
if err != nil {
return nil, err
}
keyStr = strings.ToLower(keyStr)
result, _ := p.traverseDirect(keyStr)
if result != nil {
return result, nil
}
keySegments := strings.Split(keyStr, ".")
if len(keySegments) == 1 {
return nil, nil
}
return p.traverseNested(keySegments)
}
func (p *Page) traverseDirect(key string) (interface{}, error) {
keyStr := strings.ToLower(key)
if val, ok := p.Params[keyStr]; ok {
return val, nil
}
return p.Site.Params[keyStr], nil
}
func (p *Page) traverseNested(keySegments []string) (interface{}, error) {
result := traverse(keySegments, p.Params)
if result != nil {
return result, nil
}
result = traverse(keySegments, p.Site.Params)
if result != nil {
return result, nil
}
// Didn't find anything, but also no problems.
return nil, nil
}
func traverse(keys []string, m map[string]interface{}) interface{} {
// Shift first element off.
firstKey, rest := keys[0], keys[1:]
result := m[firstKey]
// No point in continuing here.
if result == nil {
return result
}
if len(rest) == 0 {
// That was the last key.
return result
} else {
// That was not the last key.
return traverse(rest, cast.ToStringMap(result))
}
}
func (p *Page) Author() Author {
authors := p.Authors()