diff options
Diffstat (limited to 'resources/resource/params.go')
-rw-r--r-- | resources/resource/params.go | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/resources/resource/params.go b/resources/resource/params.go new file mode 100644 index 000000000..f6ecea35a --- /dev/null +++ b/resources/resource/params.go @@ -0,0 +1,89 @@ +// Copyright 2019 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package resource + +import ( + "strings" + + "github.com/spf13/cast" +) + +func Param(r ResourceParamsProvider, fallback map[string]interface{}, key interface{}) (interface{}, error) { + keyStr, err := cast.ToStringE(key) + if err != nil { + return nil, err + } + + keyStr = strings.ToLower(keyStr) + result, _ := traverseDirectParams(r, fallback, keyStr) + if result != nil { + return result, nil + } + + keySegments := strings.Split(keyStr, ".") + if len(keySegments) == 1 { + return nil, nil + } + + return traverseNestedParams(r, fallback, keySegments) +} + +func traverseDirectParams(r ResourceParamsProvider, fallback map[string]interface{}, key string) (interface{}, error) { + keyStr := strings.ToLower(key) + if val, ok := r.Params()[keyStr]; ok { + return val, nil + } + + if fallback == nil { + return nil, nil + } + + return fallback[keyStr], nil +} + +func traverseNestedParams(r ResourceParamsProvider, fallback map[string]interface{}, keySegments []string) (interface{}, error) { + result := traverseParams(keySegments, r.Params()) + if result != nil { + return result, nil + } + + if fallback != nil { + result = traverseParams(keySegments, fallback) + if result != nil { + return result, nil + } + } + + // Didn't find anything, but also no problems. + return nil, nil +} + +func traverseParams(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 + } + + // That was not the last key. + return traverseParams(rest, cast.ToStringMap(result)) +} |