langs: Use Language.Locale as primary localization key

Localization now uses Language.Locale as the golocales lookup key,
falling back to Language.Lang, then defaultContentLanguage, then "en".

Closes #9109
This commit is contained in:
Joe Mooring
2026-04-22 10:34:43 -07:00
committed by Bjørn Erik Pedersen
parent 79f030be5b
commit 1b7495bc49
2 changed files with 88 additions and 5 deletions
+7 -5
View File
@@ -79,11 +79,13 @@ func (l *Language) IsDefault() bool {
// NewLanguage creates a new language. // NewLanguage creates a new language.
func NewLanguage(lang, defaultContentLanguage, timeZone string, languageConfig LanguageConfig, logger loggers.Logger) (*Language, error) { func NewLanguage(lang, defaultContentLanguage, timeZone string, languageConfig LanguageConfig, logger loggers.Logger) (*Language, error) {
translator := golocales.New(lang) var translator golocales.Translator
if translator == nil { for _, key := range []string{languageConfig.Locale, lang, defaultContentLanguage, "en"} {
translator = golocales.New(defaultContentLanguage) if key == "" {
if translator == nil { continue
translator = golocales.New("en") }
if translator = golocales.New(key); translator != nil {
break
} }
} }
+81
View File
@@ -215,3 +215,84 @@ TITLE: {{ .Title }} RELPERMALINK: {{ .RelPermalink }}|
"b (en)|TITLE: P1 (en) RELPERMALINK: /en/p1/|", "b (en)|TITLE: P1 (en) RELPERMALINK: /en/p1/|",
) )
} }
func TestLocaleAsLocalizationKeyIssue9109(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['page','rss','section','sitemap','taxonomy','term']
defaultContentLanguage = 'de'
defaultContentLanguageInSubdir = true
[languages.de]
weight = 1
[languages.en]
locale = 'en-US'
weight = 2
[languages.fr]
locale = 'bogus'
weight = 3
[languages.nn]
weight = 4
[languages.xx]
locale = 'bogus'
weight = 5
[languages.zh-cn]
locale = 'zh-Hans'
weight = 6
-- layouts/home.html --
Time: {{ "2026-04-01T20:11:31+08:00" | time.Format ":date_long" }}|
FormatAccounting: {{ 512.5032 | lang.FormatAccounting 2 "USD" }}|
FormatCurrency: {{ 512.5032 | lang.FormatCurrency 2 "USD" }}|
`
b := hugolib.Test(t, files)
// de: no locale => localize with lang.
b.AssertFileContent("public/de/index.html",
`Time: 1. April 2026|`,
"FormatAccounting: 512,50\u00a0$|",
"FormatCurrency: 512,50\u00a0$|",
)
// en: valid locale => localize with locale.
b.AssertFileContent("public/en/index.html",
`Time: April 1, 2026|`,
`FormatAccounting: $512.50|`,
`FormatCurrency: $512.50|`,
)
// fr: invalid locale => localize with lang.
b.AssertFileContent("public/fr/index.html",
`Time: 1 avril 2026|`,
"FormatAccounting: 512,50\u00a0$US|",
"FormatCurrency: 512,50\u00a0$US|",
)
// nn: no locale => localize with lang.
b.AssertFileContent("public/nn/index.html",
`Time: 1. april 2026|`,
"FormatAccounting: 512,50\u00a0USD|",
"FormatCurrency: 512,50\u00a0USD|",
)
// xx: invalid locale + invalid lang => localize with defaultContentLanguage.
b.AssertFileContent("public/xx/index.html",
`Time: 1. April 2026|`,
"FormatAccounting: 512,50\u00a0$|",
"FormatCurrency: 512,50\u00a0$|",
)
// zh-cn: invalid lang, but valid locale => localize with locale.
b.AssertFileContent("public/zh-cn/index.html",
`Time: 2026年4月1日|`,
`FormatAccounting: US$512.50|`,
`FormatCurrency: US$512.50|`,
)
}