Use en-US as fallback when using other default language (#21200) (#21256)

Only en-US has complete translations. When use other language as
default, the en-US should still be used as fallback.

Backport #21200, Close #21199
This commit is contained in:
wxiaoguang 2022-09-25 22:14:57 +08:00 committed by GitHub
parent be5411d6b5
commit e79a10793f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 8 deletions

View file

@ -41,14 +41,14 @@ func NewLocaleStore() *LocaleStore {
} }
// AddLocaleByIni adds locale by ini into the store // AddLocaleByIni adds locale by ini into the store
func (ls *LocaleStore) AddLocaleByIni(langName, langDesc string, localeFile interface{}, otherLocaleFiles ...interface{}) error { func (ls *LocaleStore) AddLocaleByIni(langName, langDesc string, source, moreSource []byte) error {
if _, ok := ls.localeMap[langName]; ok { if _, ok := ls.localeMap[langName]; ok {
return ErrLocaleAlreadyExist return ErrLocaleAlreadyExist
} }
iniFile, err := ini.LoadSources(ini.LoadOptions{ iniFile, err := ini.LoadSources(ini.LoadOptions{
IgnoreInlineComment: true, IgnoreInlineComment: true,
UnescapeValueCommentSymbols: true, UnescapeValueCommentSymbols: true,
}, localeFile, otherLocaleFiles...) }, source, moreSource)
if err == nil { if err == nil {
iniFile.BlockMode = false iniFile.BlockMode = false
lc := &locale{store: ls, langName: langName, langDesc: langDesc, messages: iniFile} lc := &locale{store: ls, langName: langName, langDesc: langDesc, messages: iniFile}

View file

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func Test_Tr(t *testing.T) { func TestLocaleStore(t *testing.T) {
testData1 := []byte(` testData1 := []byte(`
.dot.name = Dot Name .dot.name = Dot Name
fmt = %[1]s %[2]s fmt = %[1]s %[2]s
@ -28,8 +28,8 @@ sub = Changed Sub String
`) `)
ls := NewLocaleStore() ls := NewLocaleStore()
assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1)) assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1, nil))
assert.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", testData2)) assert.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", testData2, nil))
ls.SetDefaultLang("lang1") ls.SetDefaultLang("lang1")
result := ls.Tr("lang1", "fmt", "a", "b") result := ls.Tr("lang1", "fmt", "a", "b")
@ -54,3 +54,21 @@ sub = Changed Sub String
assert.Equal(t, []string{"lang1", "lang2"}, langs) assert.Equal(t, []string{"lang1", "lang2"}, langs)
assert.Equal(t, []string{"Lang1", "Lang2"}, descs) assert.Equal(t, []string{"Lang1", "Lang2"}, descs)
} }
func TestLocaleStoreMoreSource(t *testing.T) {
testData1 := []byte(`
a=11
b=12
`)
testData2 := []byte(`
b=21
c=22
`)
ls := NewLocaleStore()
assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1, testData2))
assert.Equal(t, "11", ls.Tr("lang1", "a"))
assert.Equal(t, "21", ls.Tr("lang1", "b"))
assert.Equal(t, "22", ls.Tr("lang1", "c"))
}

View file

@ -60,9 +60,9 @@ func InitLocales() {
log.Fatal("Failed to list locale files: %v", err) log.Fatal("Failed to list locale files: %v", err)
} }
localFiles := make(map[string][]byte, len(localeNames)) localeData := make(map[string][]byte, len(localeNames))
for _, name := range localeNames { for _, name := range localeNames {
localFiles[name], err = options.Locale(name) localeData[name], err = options.Locale(name)
if err != nil { if err != nil {
log.Fatal("Failed to load %s locale file. %v", name, err) log.Fatal("Failed to load %s locale file. %v", name, err)
} }
@ -75,8 +75,16 @@ func InitLocales() {
matcher = language.NewMatcher(supportedTags) matcher = language.NewMatcher(supportedTags)
for i := range setting.Names { for i := range setting.Names {
var localeDataBase []byte
if i == 0 && setting.Langs[0] != "en-US" {
// Only en-US has complete translations. When use other language as default, the en-US should still be used as fallback.
localeDataBase = localeData["locale_en-US.ini"]
if localeDataBase == nil {
log.Fatal("Failed to load locale_en-US.ini file.")
}
}
key := "locale_" + setting.Langs[i] + ".ini" key := "locale_" + setting.Langs[i] + ".ini"
if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], localFiles[key]); err != nil { if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], localeDataBase, localeData[key]); err != nil {
log.Error("Failed to set messages to %s: %v", setting.Langs[i], err) log.Error("Failed to set messages to %s: %v", setting.Langs[i], err)
} }
} }