summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/defaultConfigProvider.go46
-rw-r--r--hugolib/config.go14
-rw-r--r--hugolib/config_test.go70
-rw-r--r--hugolib/language_test.go25
4 files changed, 135 insertions, 20 deletions
diff --git a/config/defaultConfigProvider.go b/config/defaultConfigProvider.go
index fd32c08a6..a5e2d09fd 100644
--- a/config/defaultConfigProvider.go
+++ b/config/defaultConfigProvider.go
@@ -197,6 +197,12 @@ func (c *defaultConfigProvider) Merge(k string, v interface{}) {
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 {
@@ -210,8 +216,44 @@ func (c *defaultConfigProvider) Merge(k string, v interface{}) {
// those as a special case.
for kk, vv := range p {
if pp, ok := vv.(maps.Params); ok {
- if ppp, ok := c.root[kk]; ok {
- ppp.(maps.Params).Merge(pp)
+ 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)
} else {
// We need to use the default merge strategy for
// this key.
diff --git a/hugolib/config.go b/hugolib/config.go
index 90ac7eb01..a0ce98042 100644
--- a/hugolib/config.go
+++ b/hugolib/config.go
@@ -93,20 +93,6 @@ func LoadConfig(d ConfigSourceDescriptor, doWithConfig ...func(cfg config.Provid
}
}
- // TODO(bep) improve this. This is currently needed to get the merge correctly.
- if l.cfg.IsSet("languages") {
- langs := l.cfg.GetParams("languages")
- for _, lang := range langs {
- langp := lang.(maps.Params)
- if _, ok := langp["menus"]; !ok {
- langp["menus"] = make(maps.Params)
- }
- if _, ok := langp["params"]; !ok {
- langp["params"] = make(maps.Params)
- }
- }
-
- }
l.cfg.SetDefaultMergeStrategy()
// We create languages based on the settings, so we need to make sure that
diff --git a/hugolib/config_test.go b/hugolib/config_test.go
index 65cb246b9..c5e77c946 100644
--- a/hugolib/config_test.go
+++ b/hugolib/config_test.go
@@ -76,7 +76,7 @@ func TestLoadMultiConfig(t *testing.T) {
c.Assert(cfg.GetString("DontChange"), qt.Equals, "same")
}
-func TestLoadConfigFromTheme(t *testing.T) {
+func TestLoadConfigFromThemes(t *testing.T) {
t.Parallel()
c := qt.New(t)
@@ -185,11 +185,15 @@ name = "menu-theme"
`
- buildForStrategy := func(t testing.TB, s string) *sitesBuilder {
- mainConfig := strings.ReplaceAll(mainConfigTemplate, "MERGE_PARAMS", s)
+ buildForConfig := func(mainConfig, themeConfig string) *sitesBuilder {
b := newTestSitesBuilder(t)
b.WithConfigFile("toml", mainConfig).WithThemeConfigFile("toml", themeConfig)
- return b.CreateSites().Build(BuildCfg{})
+ return b.Build(BuildCfg{})
+ }
+
+ buildForStrategy := func(t testing.TB, s string) *sitesBuilder {
+ mainConfig := strings.ReplaceAll(mainConfigTemplate, "MERGE_PARAMS", s)
+ return buildForConfig(mainConfig, themeConfig)
}
c.Run("Merge default", func(c *qt.C) {
@@ -316,6 +320,64 @@ name = "menu-theme"
})
})
+ c.Run("Merge no params in project", func(c *qt.C) {
+ b := buildForConfig(
+ "baseURL=\"https://example.org\"\ntheme = \"test-theme\"\n",
+ "[params]\np1 = \"p1 theme\"\n",
+ )
+
+ got := b.Cfg.Get("").(maps.Params)
+
+ b.Assert(got["params"], qt.DeepEquals, maps.Params{
+ "p1": "p1 theme",
+ })
+ })
+
+ c.Run("Merge language no menus or params in project", func(c *qt.C) {
+ b := buildForConfig(
+ `
+theme = "test-theme"
+baseURL = "https://example.com/"
+
+[languages]
+[languages.en]
+languageName = "English"
+
+`,
+ `
+[languages]
+[languages.en]
+languageName = "EnglishTheme"
+
+[languages.en.params]
+p1="themep1"
+
+[[languages.en.menus.main]]
+name = "menu-theme"
+`,
+ )
+
+ got := b.Cfg.Get("").(maps.Params)
+
+ b.Assert(got["languages"], qt.DeepEquals,
+ maps.Params{
+ "en": maps.Params{
+ "languagename": "English",
+ "menus": maps.Params{
+ "main": []map[string]interface{}{
+ {
+ "name": "menu-theme",
+ },
+ },
+ },
+ "params": maps.Params{
+ "p1": "themep1",
+ },
+ },
+ },
+ )
+ })
+
}
func TestLoadConfigFromThemeDir(t *testing.T) {
diff --git a/hugolib/language_test.go b/hugolib/language_test.go
index 16dcbcb03..da8ecd22b 100644
--- a/hugolib/language_test.go
+++ b/hugolib/language_test.go
@@ -54,3 +54,28 @@ weight = 1
b.AssertFileContent("public/index.html", "Hello: Hello")
})
}
+
+func TestLanguageBugs(t *testing.T) {
+ c := qt.New(t)
+
+ // Issue #8672
+ c.Run("Config with language, menu in root only", func(c *qt.C) {
+ b := newTestSitesBuilder(c)
+ b.WithConfigFile("toml", `
+theme = "test-theme"
+[[menus.foo]]
+name = "foo-a"
+[languages.en]
+
+`,
+ )
+
+ b.WithThemeConfigFile("toml", `[languages.en]`)
+
+ b.Build(BuildCfg{})
+
+ menus := b.H.Sites[0].Menus()
+ c.Assert(menus, qt.HasLen, 1)
+
+ })
+}