Skip to content

Commit 6be463b

Browse files
bepchalin
andauthored
langs/i18n: Prefer languageCode when picking translation file
Fixes #14204 Closes #14217 Co-authored-by: Patrice Chalin <pchalin@gmail.com>
1 parent 9e24b56 commit 6be463b

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

‎langs/i18n/i18n.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ func NewTranslator(b *i18n.Bundle, cfg config.AllProvider, logger loggers.Logger
4545
return t
4646
}
4747

48+
// Lookup looks up the translate func for the given language.
49+
func (t Translator) Lookup(lang string) (translateFunc, bool) {
50+
f, ok := t.translateFuncs[lang]
51+
return f, ok
52+
}
53+
4854
// Func gets the translate func for the given language, or for the default
4955
// configured language if not found.
5056
func (t Translator) Func(lang string) translateFunc {

‎langs/i18n/i18n_integration_test.go‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package i18n_test
1515

1616
import (
17+
"strings"
1718
"testing"
1819

1920
qt "github.com/frankban/quicktest"
@@ -165,3 +166,57 @@ b = 'b translated'
165166
b.Assert(err, qt.IsNotNil)
166167
b.Assert(err.Error(), qt.Contains, "failed to load translations: reserved keys [description] mixed with unreserved keys [a b]: see the lang.Translate documentation for a list of reserved keys")
167168
}
169+
170+
func TestI18nUseLanguageCodeWhenBothTranslationFilesArePresent(t *testing.T) {
171+
t.Parallel()
172+
173+
filesTemplate := `
174+
-- hugo.yaml --
175+
languages:
176+
en:
177+
languageCode: en-us
178+
-- i18n/en.yml --
179+
hello: Greetings from en!
180+
-- i18n/en-us.yml --
181+
hello: Greetings from en-us!
182+
-- layouts/all.html --
183+
{{ T "hello" }}
184+
`
185+
186+
runTest := func(s string) {
187+
b := hugolib.Test(t, s)
188+
b.AssertFileContent("public/index.html", `Greetings from en-us!`)
189+
}
190+
191+
runTest(filesTemplate)
192+
runTest(strings.ReplaceAll(filesTemplate, "languageCode: en-us", "languageCode: En-US"))
193+
runTest(strings.ReplaceAll(filesTemplate, "-- i18n/en-us.yml --", "-- i18n/en-US.yml --"))
194+
}
195+
196+
func TestI18nUseLangWhenLanguageCodeFileIsMissing(t *testing.T) {
197+
t.Parallel()
198+
199+
filesTemplate := `
200+
-- hugo.yaml --
201+
languages:
202+
en:
203+
title: English
204+
pt:
205+
languageCode: pt-br
206+
-- i18n/en.yml --
207+
hello: Greetings from en!
208+
-- i18n/pt.yml --
209+
hello: Greetings from pt!
210+
-- layouts/all.html --
211+
{{ T "hello" }}
212+
`
213+
214+
runTest := func(s string) {
215+
b := hugolib.Test(t, s)
216+
b.AssertFileContent("public/pt/index.html", `Greetings from pt!`)
217+
}
218+
219+
runTest(filesTemplate)
220+
runTest(strings.ReplaceAll(filesTemplate, "pt:", "PT:"))
221+
runTest(strings.ReplaceAll(filesTemplate, "-- i18n/pt.yml --", "-- i18n/pT.yml --"))
222+
}

‎langs/i18n/translationProvider.go‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func (tp *TranslationProvider) NewResource(dst *deps.Deps) error {
7878

7979
tp.t = NewTranslator(bundle, dst.Conf, dst.Log)
8080

81-
dst.Translate = tp.t.Func(dst.Conf.Language().(*langs.Language).Lang)
81+
dst.Translate = tp.getTranslateFunc(dst)
8282

8383
return nil
8484
}
@@ -128,10 +128,23 @@ func addTranslationFile(bundle *i18n.Bundle, r *source.File) error {
128128

129129
// CloneResource sets the language func for the new language.
130130
func (tp *TranslationProvider) CloneResource(dst, src *deps.Deps) error {
131-
dst.Translate = tp.t.Func(dst.Conf.Language().(*langs.Language).Lang)
131+
dst.Translate = tp.getTranslateFunc(dst)
132132
return nil
133133
}
134134

135+
// getTranslateFunc returns the translation function for the language in Deps.
136+
// We first try the language code (e.g. "en-US"), then the language key (e.g. "en").
137+
func (tp *TranslationProvider) getTranslateFunc(dst *deps.Deps) func(ctx context.Context, translationID string, templateData any) string {
138+
l := dst.Conf.Language().(*langs.Language)
139+
if lc := l.LanguageCode(); lc != "" {
140+
if fn, ok := tp.t.Lookup(strings.ToLower(lc)); ok {
141+
return fn
142+
}
143+
}
144+
// Func will fall back to the default language if not found.
145+
return tp.t.Func(l.Lang)
146+
}
147+
135148
func errWithFileContext(inerr error, r *source.File) error {
136149
meta := r.FileInfo().Meta()
137150
realFilename := meta.Filename

0 commit comments

Comments
 (0)