@@ -30,16 +30,22 @@ type locale struct {
3030
3131type LocaleStore struct {
3232 // After initializing has finished, these fields are read-only.
33- langNames []string
34- langDescs []string
35- langOffsets []int
36- offsetToTranslationMap []map [string ]string
37- localeMap map [string ]* locale
38- defaultLang string
33+ langNames []string
34+ langDescs []string
35+
36+ langOffsets []int
37+ translationKeys []string
38+ keyToOffset map [string ]int
39+ translationValues []string
40+
41+ localeMap map [string ]* locale
42+
43+ defaultLang string
44+ defaultLangKeysLen int
3945}
4046
4147func NewLocaleStore () * LocaleStore {
42- return & LocaleStore {localeMap : make (map [string ]* locale )}
48+ return & LocaleStore {localeMap : make (map [string ]* locale ), keyToOffset : make ( map [ string ] int ) }
4349}
4450
4551// AddLocaleByIni adds locale by ini into the store
@@ -63,15 +69,44 @@ func (ls *LocaleStore) AddLocaleByIni(langName, langDesc string, localeFile inte
6369 // For development, live-reload of the translation files is important.
6470 // For production, we can do some expensive work and then make the querying fast.
6571 if setting .IsProd {
66- keyToValue := map [string ]string {}
67- // Go trough all keys and store key->value into a map.
68- for _ , section := range iniFile .Sections () {
69- for _ , key := range section .Keys () {
70- keyToValue [strings .TrimPrefix (section .Name ()+ "." + key .Name (), "DEFAULT." )] = key .Value ()
72+ // If the language is the default language, then we go trough all keys. These keys
73+ // will become the keys that we consider to support and take into account while going
74+ // trough querying translation keys.
75+ if langName == ls .defaultLang {
76+ idx := 0
77+ // Store all key, value into two slices.
78+ for _ , section := range iniFile .Sections () {
79+ for _ , key := range section .Keys () {
80+ ls .translationKeys = append (ls .translationKeys , section .Name ()+ "#" + key .Name ())
81+ ls .translationValues = append (ls .translationValues , key .Value ())
82+
83+ ls .keyToOffset [strings .TrimPrefix (section .Name ()+ "." + key .Name (), "DEFAULT." )] = idx
84+ idx ++
85+ }
86+ }
87+
88+ ls .defaultLangKeysLen = len (ls .translationKeys )
89+ } else {
90+ // Go trough all the keys that the defaultLang has and append it to translationValues.
91+ // If the lang doesn't have a value for the translation, use the defaultLang's one.
92+ for i := 0 ; i < ls .defaultLangKeysLen ; i ++ {
93+ splitted := strings .SplitN (ls .translationKeys [i ], "#" , 2 )
94+ // TODO: optimize for repeated sequential access of section.
95+ section , err := iniFile .GetSection (splitted [0 ])
96+ if err != nil {
97+ // Section not found? Use the defaultLang's value for this translation key.
98+ ls .translationValues = append (ls .translationValues , ls .translationValues [i ])
99+ continue
100+ }
101+ key , err := section .GetKey (splitted [1 ])
102+ if err != nil {
103+ // Key not found? Use the defaultLang's value for this translation key.
104+ ls .translationValues = append (ls .translationValues , ls .translationValues [i ])
105+ continue
106+ }
107+ ls .translationValues = append (ls .translationValues , key .Value ())
71108 }
72109 }
73- // Append the key->value to the offsetToTranslationMap variable.
74- ls .offsetToTranslationMap = append (ls .offsetToTranslationMap , keyToValue )
75110
76111 // Help Go's GC.
77112 iniFile = nil
@@ -175,12 +210,12 @@ func Tr(lang, trKey string, trArgs ...interface{}) string {
175210}
176211
177212func TrOffset (offset int , trKey string , trArgs ... interface {}) string {
178- languageTranslationMap := DefaultLocales .offsetToTranslationMap [offset ]
179- trMsg , ok := languageTranslationMap [trKey ]
180- if ! ok {
181- return trKey
182- }
213+ // Get the offset of the translation key.
214+ keyOffset := DefaultLocales .keyToOffset [trKey ]
215+ // Now adjust to use the language's translation of the key.
216+ keyOffset += offset * DefaultLocales .defaultLangKeysLen
183217
218+ trMsg := DefaultLocales .translationValues [keyOffset ]
184219 if len (trArgs ) > 0 {
185220 fmtArgs := make ([]interface {}, 0 , len (trArgs ))
186221 for _ , arg := range trArgs {
0 commit comments