summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-01-30 17:51:18 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2018-01-30 18:53:07 +0100
commitae742cb1bdf35b81aa0ede5453da6b0c4a4fccf2 (patch)
treef2922d4343f9819e7ff4220ebc333b467c8f0d4b
parentfeeed073c3320b09fb38168ce272ac88b987f1d2 (diff)
Fix language params handling
This fixes some issues with language params handling by separating params from configuration values per language. This means that you can now do this: ```toml [languages] [languages.en] languageName = "English" weight = 1 title = "My Cool Site" [languages.en.params] myParam = "Hi!" ``` This is not a breaking change, but the above is a less suprising way of configuring custom params. It also fixes some hard-to-debug corner-cases in multilingual sites. Fixes #4356 Fixes #4352
-rw-r--r--helpers/language.go35
-rw-r--r--helpers/language_test.go17
-rw-r--r--hugolib/hugo_sites_build_test.go28
-rw-r--r--hugolib/multilingual.go10
4 files changed, 67 insertions, 23 deletions
diff --git a/helpers/language.go b/helpers/language.go
index 934c82de0..49a25ccf7 100644
--- a/helpers/language.go
+++ b/helpers/language.go
@@ -16,7 +16,6 @@ package helpers
import (
"sort"
"strings"
- "sync"
"github.com/gohugoio/hugo/config"
"github.com/spf13/cast"
@@ -42,9 +41,16 @@ type Language struct {
Title string
Weight int
- Cfg config.Provider
- params map[string]interface{}
- paramsInit sync.Once
+ Cfg config.Provider
+
+ // These are params declared in the [params] section of the language merged with the
+ // site's params, the most specific (language) wins on duplicate keys.
+ params map[string]interface{}
+
+ // These are config values, i.e. the settings declared outside of the [params] section of the language.
+ // This is the map Hugo looks in when looking for configuration values (baseURL etc.).
+ // Values in this map can also be fetched from the params map above.
+ settings map[string]interface{}
}
func (l *Language) String() string {
@@ -53,15 +59,14 @@ func (l *Language) String() string {
// NewLanguage creates a new language.
func NewLanguage(lang string, cfg config.Provider) *Language {
+ // Note that language specific params will be overridden later.
+ // We should improve that, but we need to make a copy:
params := make(map[string]interface{})
- // Merge with global config.
- globalParams := cfg.GetStringMap("params")
- for k, v := range globalParams {
- if _, ok := params[k]; !ok {
- params[k] = v
- }
+ for k, v := range cfg.GetStringMap("params") {
+ params[k] = v
}
- l := &Language{Lang: lang, Cfg: cfg, params: params}
+ ToLowerMap(params)
+ l := &Language{Lang: lang, Cfg: cfg, params: params, settings: make(map[string]interface{})}
return l
}
@@ -115,7 +120,7 @@ func (l Languages) IsMultihost() bool {
return false
}
-// SetParam sets param with the given key and value.
+// SetParam sets a param with the given key and value.
// SetParam is case-insensitive.
func (l *Language) SetParam(k string, v interface{}) {
l.params[strings.ToLower(k)] = v
@@ -166,7 +171,7 @@ func (l *Language) GetLocal(key string) interface{} {
}
key = strings.ToLower(key)
if !globalOnlySettings[key] {
- if v, ok := l.params[key]; ok {
+ if v, ok := l.settings[key]; ok {
return v
}
}
@@ -179,7 +184,7 @@ func (l *Language) Set(key string, value interface{}) {
panic("language not set")
}
key = strings.ToLower(key)
- l.params[key] = value
+ l.settings[key] = value
}
// IsSet checks whether the key is set in the language or the related config store.
@@ -188,7 +193,7 @@ func (l *Language) IsSet(key string) bool {
key = strings.ToLower(key)
if !globalOnlySettings[key] {
- if _, ok := l.params[key]; ok {
+ if _, ok := l.settings[key]; ok {
return true
}
}
diff --git a/helpers/language_test.go b/helpers/language_test.go
index 902177e1a..68ee3506d 100644
--- a/helpers/language_test.go
+++ b/helpers/language_test.go
@@ -23,11 +23,24 @@ import (
func TestGetGlobalOnlySetting(t *testing.T) {
v := viper.New()
lang := NewDefaultLanguage(v)
- lang.SetParam("defaultContentLanguageInSubdir", false)
- lang.SetParam("paginatePath", "side")
+ lang.Set("defaultContentLanguageInSubdir", false)
+ lang.Set("paginatePath", "side")
v.Set("defaultContentLanguageInSubdir", true)
v.Set("paginatePath", "page")
require.True(t, lang.GetBool("defaultContentLanguageInSubdir"))
require.Equal(t, "side", lang.GetString("paginatePath"))
}
+
+func TestLanguageParams(t *testing.T) {
+ assert := require.New(t)
+
+ v := viper.New()
+ v.Set("p1", "p1cfg")
+
+ lang := NewDefaultLanguage(v)
+ lang.SetParam("p1", "p1p")
+
+ assert.Equal("p1p", lang.Params()["p1"])
+ assert.Equal("p1cfg", lang.Get("p1"))
+}
diff --git a/hugolib/hugo_sites_build_test.go b/hugolib/hugo_sites_build_test.go
index cc3a940de..0cececfd7 100644
--- a/hugolib/hugo_sites_build_test.go
+++ b/hugolib/hugo_sites_build_test.go
@@ -141,6 +141,9 @@ func doTestMultiSitesMainLangInRoot(t *testing.T, defaultInSubDir bool) {
func TestMultiSitesWithTwoLanguages(t *testing.T) {
t.Parallel()
+
+ assert := require.New(t)
+
mm := afero.NewMemMapFs()
writeToFs(t, mm, "config.toml", `
@@ -152,11 +155,15 @@ defaultContentLanguage = "nn"
languageName = "Nynorsk"
weight = 1
title = "Tittel på Nynorsk"
+[languages.nn.params]
+p1 = "p1nn"
[languages.en]
title = "Title in English"
languageName = "English"
weight = 2
+[languages.en.params]
+p1 = "p1en"
`,
)
@@ -176,15 +183,24 @@ weight = 2
// Add some data
writeSource(t, fs, filepath.Join("data", "hugo.toml"), "slogan = \"Hugo Rocks!\"")
- require.NoError(t, sites.Build(BuildCfg{}))
- require.Len(t, sites.Sites, 2)
+ assert.NoError(sites.Build(BuildCfg{}))
+ assert.Len(sites.Sites, 2)
nnSite := sites.Sites[0]
- nnSiteHome := nnSite.getPage(KindHome)
- require.Len(t, nnSiteHome.AllTranslations(), 2)
- require.Len(t, nnSiteHome.Translations(), 1)
- require.True(t, nnSiteHome.IsTranslated())
+ nnHome := nnSite.getPage(KindHome)
+ assert.Len(nnHome.AllTranslations(), 2)
+ assert.Len(nnHome.Translations(), 1)
+ assert.True(nnHome.IsTranslated())
+
+ enHome := sites.Sites[1].getPage(KindHome)
+
+ p1, err := enHome.Param("p1")
+ assert.NoError(err)
+ assert.Equal("p1en", p1)
+ p1, err = nnHome.Param("p1")
+ assert.NoError(err)
+ assert.Equal("p1nn", p1)
}
//
diff --git a/hugolib/multilingual.go b/hugolib/multilingual.go
index 589df66e0..101de7ace 100644
--- a/hugolib/multilingual.go
+++ b/hugolib/multilingual.go
@@ -111,10 +111,20 @@ func toSortedLanguages(cfg config.Provider, l map[string]interface{}) (helpers.L
language.LanguageName = cast.ToString(v)
case "weight":
language.Weight = cast.ToInt(v)
+ case "params":
+ m := cast.ToStringMap(v)
+ // Needed for case insensitive fetching of params values
+ helpers.ToLowerMap(m)
+ for k, vv := range m {
+ language.SetParam(k, vv)
+ }
}
// Put all into the Params map
language.SetParam(loki, v)
+
+ // Also set it in the configuration map (for baseURL etc.)
+ language.Set(loki, v)
}
langs[i] = language