mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00:00 
			
		
		
		
	Use en-US as fallback when using other default language (#21200)
Only en-US has complete translations. When use other language as default, the en-US should still be used as fallback. Close #21199 ### Screenshot  Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
		@@ -34,7 +34,7 @@ type LocaleStore interface {
 | 
				
			|||||||
	// HasLang returns whether a given language is present in the store
 | 
						// HasLang returns whether a given language is present in the store
 | 
				
			||||||
	HasLang(langName string) bool
 | 
						HasLang(langName string) bool
 | 
				
			||||||
	// AddLocaleByIni adds a new language to the store
 | 
						// AddLocaleByIni adds a new language to the store
 | 
				
			||||||
	AddLocaleByIni(langName, langDesc string, source interface{}) error
 | 
						AddLocaleByIni(langName, langDesc string, source, moreSource []byte) error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ResetDefaultLocales resets the current default locales
 | 
					// ResetDefaultLocales resets the current default locales
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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")
 | 
				
			||||||
@@ -58,3 +58,21 @@ sub = Changed Sub String
 | 
				
			|||||||
	assert.False(t, found)
 | 
						assert.False(t, found)
 | 
				
			||||||
	assert.NoError(t, ls.Close())
 | 
						assert.NoError(t, ls.Close())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,9 +37,7 @@ func NewLocaleStore() LocaleStore {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AddLocaleByIni adds locale by ini into the store
 | 
					// AddLocaleByIni adds locale by ini into the store
 | 
				
			||||||
// if source is a string, then the file is loaded
 | 
					func (store *localeStore) AddLocaleByIni(langName, langDesc string, source, moreSource []byte) error {
 | 
				
			||||||
// if source is a []byte, then the content is used
 | 
					 | 
				
			||||||
func (store *localeStore) AddLocaleByIni(langName, langDesc string, source interface{}) error {
 | 
					 | 
				
			||||||
	if _, ok := store.localeMap[langName]; ok {
 | 
						if _, ok := store.localeMap[langName]; ok {
 | 
				
			||||||
		return ErrLocaleAlreadyExist
 | 
							return ErrLocaleAlreadyExist
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -53,7 +51,7 @@ func (store *localeStore) AddLocaleByIni(langName, langDesc string, source inter
 | 
				
			|||||||
	iniFile, err := ini.LoadSources(ini.LoadOptions{
 | 
						iniFile, err := ini.LoadSources(ini.LoadOptions{
 | 
				
			||||||
		IgnoreInlineComment:         true,
 | 
							IgnoreInlineComment:         true,
 | 
				
			||||||
		UnescapeValueCommentSymbols: true,
 | 
							UnescapeValueCommentSymbols: true,
 | 
				
			||||||
	}, source)
 | 
						}, source, moreSource)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fmt.Errorf("unable to load ini: %w", err)
 | 
							return fmt.Errorf("unable to load ini: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -60,9 +60,9 @@ func InitLocales(ctx context.Context) {
 | 
				
			|||||||
			log.Fatal("Failed to list locale files: %v", err)
 | 
								log.Fatal("Failed to list locale files: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		localFiles := make(map[string]interface{}, 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,9 +75,17 @@ func InitLocales(ctx context.Context) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		matcher = language.NewMatcher(supportedTags)
 | 
							matcher = language.NewMatcher(supportedTags)
 | 
				
			||||||
		for i := range setting.Names {
 | 
							for i := range setting.Names {
 | 
				
			||||||
			key := "locale_" + setting.Langs[i] + ".ini"
 | 
								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.")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], localFiles[key]); err != nil {
 | 
								key := "locale_" + setting.Langs[i] + ".ini"
 | 
				
			||||||
 | 
								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)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user