mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-29 22:29:56 +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,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/hugofs/glob"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
@@ -80,43 +81,90 @@ func (m PageMatcher) Matches(p Page) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// DecodeCascade decodes in which could be either a map or a slice of maps.
|
||||
func DecodeCascade(in any) (map[PageMatcher]maps.Params, error) {
|
||||
m, err := maps.ToSliceStringMap(in)
|
||||
if err != nil {
|
||||
return map[PageMatcher]maps.Params{
|
||||
{}: maps.ToStringMap(in),
|
||||
}, nil
|
||||
}
|
||||
func DecodeCascadeConfig(in any) (*config.ConfigNamespace[[]PageMatcherParamsConfig, map[PageMatcher]maps.Params], error) {
|
||||
buildConfig := func(in any) (map[PageMatcher]maps.Params, any, error) {
|
||||
cascade := make(map[PageMatcher]maps.Params)
|
||||
if in == nil {
|
||||
return cascade, []map[string]any{}, nil
|
||||
}
|
||||
ms, err := maps.ToSliceStringMap(in)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cascade := make(map[PageMatcher]maps.Params)
|
||||
var cfgs []PageMatcherParamsConfig
|
||||
|
||||
for _, vv := range m {
|
||||
var m PageMatcher
|
||||
if mv, found := vv["_target"]; found {
|
||||
err := DecodePageMatcher(mv, &m)
|
||||
for _, m := range ms {
|
||||
m = maps.CleanConfigStringMap(m)
|
||||
c, err := mapToPageMatcherParamsConfig(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
cfgs = append(cfgs, c)
|
||||
}
|
||||
c, found := cascade[m]
|
||||
if found {
|
||||
// Merge
|
||||
for k, v := range vv {
|
||||
if _, found := c[k]; !found {
|
||||
c[k] = v
|
||||
|
||||
for _, cfg := range cfgs {
|
||||
m := cfg.Target
|
||||
c, found := cascade[m]
|
||||
if found {
|
||||
// Merge
|
||||
for k, v := range cfg.Params {
|
||||
if _, found := c[k]; !found {
|
||||
c[k] = v
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cascade[m] = cfg.Params
|
||||
}
|
||||
} else {
|
||||
cascade[m] = vv
|
||||
}
|
||||
|
||||
return cascade, cfgs, nil
|
||||
}
|
||||
|
||||
return cascade, nil
|
||||
return config.DecodeNamespace[[]PageMatcherParamsConfig](in, buildConfig)
|
||||
|
||||
}
|
||||
|
||||
// DecodePageMatcher decodes m into v.
|
||||
func DecodePageMatcher(m any, v *PageMatcher) error {
|
||||
// DecodeCascade decodes in which could be either a map or a slice of maps.
|
||||
func DecodeCascade(in any) (map[PageMatcher]maps.Params, error) {
|
||||
conf, err := DecodeCascadeConfig(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conf.Config, nil
|
||||
}
|
||||
|
||||
func mapToPageMatcherParamsConfig(m map[string]any) (PageMatcherParamsConfig, error) {
|
||||
var pcfg PageMatcherParamsConfig
|
||||
for k, v := range m {
|
||||
switch strings.ToLower(k) {
|
||||
case "params":
|
||||
// We simplified the structure of the cascade config in Hugo 0.111.0.
|
||||
// There is a small chance that someone has used the old structure with the params keyword,
|
||||
// those values will now be moved to the top level.
|
||||
// This should be very unlikely as it would lead to constructs like .Params.params.foo,
|
||||
// and most people see params as an Hugo internal keyword.
|
||||
pcfg.Params = maps.ToStringMap(v)
|
||||
case "_target", "target":
|
||||
var target PageMatcher
|
||||
if err := decodePageMatcher(v, &target); err != nil {
|
||||
return pcfg, err
|
||||
}
|
||||
pcfg.Target = target
|
||||
default:
|
||||
// Legacy config.
|
||||
if pcfg.Params == nil {
|
||||
pcfg.Params = make(maps.Params)
|
||||
}
|
||||
pcfg.Params[k] = v
|
||||
}
|
||||
}
|
||||
return pcfg, pcfg.init()
|
||||
|
||||
}
|
||||
|
||||
// decodePageMatcher decodes m into v.
|
||||
func decodePageMatcher(m any, v *PageMatcher) error {
|
||||
if err := mapstructure.WeakDecode(m, v); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -140,3 +188,14 @@ func DecodePageMatcher(m any, v *PageMatcher) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type PageMatcherParamsConfig struct {
|
||||
// Apply Params to all Pages matching Target.
|
||||
Params maps.Params
|
||||
Target PageMatcher
|
||||
}
|
||||
|
||||
func (p *PageMatcherParamsConfig) init() error {
|
||||
maps.PrepareParams(p.Params)
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user