mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-11 20:03:58 +02:00
Create a struct with all of Hugo's config options
Primary motivation is documentation, but it will also hopefully simplify the code. Also, * Lower case the default output format names; this is in line with the custom ones (map keys) and how it's treated all the places. This avoids doing `stringds.EqualFold` everywhere. Closes #10896 Closes #10620
This commit is contained in:
@@ -19,6 +19,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
xmaps "golang.org/x/exp/maps"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
@@ -75,11 +77,6 @@ func NewFrom(params maps.Params) Provider {
|
||||
}
|
||||
}
|
||||
|
||||
// NewWithTestDefaults is used in tests only.
|
||||
func NewWithTestDefaults() Provider {
|
||||
return SetBaseTestDefaults(New())
|
||||
}
|
||||
|
||||
// defaultConfigProvider is a Provider backed by a map where all keys are lower case.
|
||||
// All methods are thread safe.
|
||||
type defaultConfigProvider struct {
|
||||
@@ -160,9 +157,9 @@ func (c *defaultConfigProvider) Set(k string, v any) {
|
||||
k = strings.ToLower(k)
|
||||
|
||||
if k == "" {
|
||||
if p, ok := maps.ToParamsAndPrepare(v); ok {
|
||||
if p, err := maps.ToParamsAndPrepare(v); err == nil {
|
||||
// Set the values directly in root.
|
||||
c.root.Set(p)
|
||||
maps.SetParams(c.root, p)
|
||||
} else {
|
||||
c.root[k] = v
|
||||
}
|
||||
@@ -184,7 +181,7 @@ func (c *defaultConfigProvider) Set(k string, v any) {
|
||||
if existing, found := m[key]; found {
|
||||
if p1, ok := existing.(maps.Params); ok {
|
||||
if p2, ok := v.(maps.Params); ok {
|
||||
p1.Set(p2)
|
||||
maps.SetParams(p1, p2)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -208,12 +205,6 @@ func (c *defaultConfigProvider) Merge(k string, v any) {
|
||||
defer c.mu.Unlock()
|
||||
k = strings.ToLower(k)
|
||||
|
||||
const (
|
||||
languagesKey = "languages"
|
||||
paramsKey = "params"
|
||||
menusKey = "menus"
|
||||
)
|
||||
|
||||
if k == "" {
|
||||
rs, f := c.root.GetMergeStrategy()
|
||||
if f && rs == maps.ParamsMergeStrategyNone {
|
||||
@@ -222,7 +213,7 @@ func (c *defaultConfigProvider) Merge(k string, v any) {
|
||||
return
|
||||
}
|
||||
|
||||
if p, ok := maps.ToParamsAndPrepare(v); ok {
|
||||
if p, err := maps.ToParamsAndPrepare(v); err == nil {
|
||||
// As there may be keys in p not in root, we need to handle
|
||||
// those as a special case.
|
||||
var keysToDelete []string
|
||||
@@ -230,49 +221,14 @@ func (c *defaultConfigProvider) Merge(k string, v any) {
|
||||
if pp, ok := vv.(maps.Params); ok {
|
||||
if pppi, ok := c.root[kk]; ok {
|
||||
ppp := pppi.(maps.Params)
|
||||
if kk == languagesKey {
|
||||
// Languages is currently a special case.
|
||||
// We may have languages with menus or params in the
|
||||
// right map that is not present in the left map.
|
||||
// With the default merge strategy those items will not
|
||||
// be passed over.
|
||||
var hasParams, hasMenus bool
|
||||
for _, rv := range pp {
|
||||
if lkp, ok := rv.(maps.Params); ok {
|
||||
_, hasMenus = lkp[menusKey]
|
||||
_, hasParams = lkp[paramsKey]
|
||||
}
|
||||
}
|
||||
|
||||
if hasMenus || hasParams {
|
||||
for _, lv := range ppp {
|
||||
if lkp, ok := lv.(maps.Params); ok {
|
||||
if hasMenus {
|
||||
if _, ok := lkp[menusKey]; !ok {
|
||||
p := maps.Params{}
|
||||
p.SetDefaultMergeStrategy(maps.ParamsMergeStrategyShallow)
|
||||
lkp[menusKey] = p
|
||||
}
|
||||
}
|
||||
if hasParams {
|
||||
if _, ok := lkp[paramsKey]; !ok {
|
||||
p := maps.Params{}
|
||||
p.SetDefaultMergeStrategy(maps.ParamsMergeStrategyShallow)
|
||||
lkp[paramsKey] = p
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ppp.Merge(pp)
|
||||
maps.MergeParamsWithStrategy("", ppp, pp)
|
||||
} else {
|
||||
// We need to use the default merge strategy for
|
||||
// this key.
|
||||
np := make(maps.Params)
|
||||
strategy := c.determineMergeStrategy(KeyParams{Key: "", Params: c.root}, KeyParams{Key: kk, Params: np})
|
||||
np.SetDefaultMergeStrategy(strategy)
|
||||
np.Merge(pp)
|
||||
strategy := c.determineMergeStrategy(maps.KeyParams{Key: "", Params: c.root}, maps.KeyParams{Key: kk, Params: np})
|
||||
np.SetMergeStrategy(strategy)
|
||||
maps.MergeParamsWithStrategy("", np, pp)
|
||||
c.root[kk] = np
|
||||
if np.IsZero() {
|
||||
// Just keep it until merge is done.
|
||||
@@ -282,7 +238,7 @@ func (c *defaultConfigProvider) Merge(k string, v any) {
|
||||
}
|
||||
}
|
||||
// Merge the rest.
|
||||
c.root.MergeRoot(p)
|
||||
maps.MergeParams(c.root, p)
|
||||
for _, k := range keysToDelete {
|
||||
delete(c.root, k)
|
||||
}
|
||||
@@ -307,7 +263,7 @@ func (c *defaultConfigProvider) Merge(k string, v any) {
|
||||
if existing, found := m[key]; found {
|
||||
if p1, ok := existing.(maps.Params); ok {
|
||||
if p2, ok := v.(maps.Params); ok {
|
||||
p1.Merge(p2)
|
||||
maps.MergeParamsWithStrategy("", p1, p2)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -315,9 +271,15 @@ func (c *defaultConfigProvider) Merge(k string, v any) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *defaultConfigProvider) WalkParams(walkFn func(params ...KeyParams) bool) {
|
||||
var walk func(params ...KeyParams)
|
||||
walk = func(params ...KeyParams) {
|
||||
func (c *defaultConfigProvider) Keys() []string {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
return xmaps.Keys(c.root)
|
||||
}
|
||||
|
||||
func (c *defaultConfigProvider) WalkParams(walkFn func(params ...maps.KeyParams) bool) {
|
||||
var walk func(params ...maps.KeyParams)
|
||||
walk = func(params ...maps.KeyParams) {
|
||||
if walkFn(params...) {
|
||||
return
|
||||
}
|
||||
@@ -325,17 +287,17 @@ func (c *defaultConfigProvider) WalkParams(walkFn func(params ...KeyParams) bool
|
||||
i := len(params)
|
||||
for k, v := range p1.Params {
|
||||
if p2, ok := v.(maps.Params); ok {
|
||||
paramsplus1 := make([]KeyParams, i+1)
|
||||
paramsplus1 := make([]maps.KeyParams, i+1)
|
||||
copy(paramsplus1, params)
|
||||
paramsplus1[i] = KeyParams{Key: k, Params: p2}
|
||||
paramsplus1[i] = maps.KeyParams{Key: k, Params: p2}
|
||||
walk(paramsplus1...)
|
||||
}
|
||||
}
|
||||
}
|
||||
walk(KeyParams{Key: "", Params: c.root})
|
||||
walk(maps.KeyParams{Key: "", Params: c.root})
|
||||
}
|
||||
|
||||
func (c *defaultConfigProvider) determineMergeStrategy(params ...KeyParams) maps.ParamsMergeStrategy {
|
||||
func (c *defaultConfigProvider) determineMergeStrategy(params ...maps.KeyParams) maps.ParamsMergeStrategy {
|
||||
if len(params) == 0 {
|
||||
return maps.ParamsMergeStrategyNone
|
||||
}
|
||||
@@ -391,13 +353,8 @@ func (c *defaultConfigProvider) determineMergeStrategy(params ...KeyParams) maps
|
||||
return strategy
|
||||
}
|
||||
|
||||
type KeyParams struct {
|
||||
Key string
|
||||
Params maps.Params
|
||||
}
|
||||
|
||||
func (c *defaultConfigProvider) SetDefaultMergeStrategy() {
|
||||
c.WalkParams(func(params ...KeyParams) bool {
|
||||
c.WalkParams(func(params ...maps.KeyParams) bool {
|
||||
if len(params) == 0 {
|
||||
return false
|
||||
}
|
||||
@@ -409,7 +366,7 @@ func (c *defaultConfigProvider) SetDefaultMergeStrategy() {
|
||||
}
|
||||
strategy := c.determineMergeStrategy(params...)
|
||||
if strategy != "" {
|
||||
p.SetDefaultMergeStrategy(strategy)
|
||||
p.SetMergeStrategy(strategy)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
Reference in New Issue
Block a user