-
Notifications
You must be signed in to change notification settings - Fork 7.1k
/
i18n.go
138 lines (113 loc) · 4.15 KB
/
i18n.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package utils
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"
"github.com/mattermost/go-i18n/i18n"
"github.com/mattermost/mattermost-server/v5/mlog"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/utils/fileutils"
)
var T i18n.TranslateFunc
var TDefault i18n.TranslateFunc
var locales map[string]string = make(map[string]string)
var settings model.LocalizationSettings
// this functions loads translations from filesystem if they are not
// loaded already and assigns english while loading server config
func TranslationsPreInit() error {
if T != nil {
return nil
}
// Set T even if we fail to load the translations. Lots of shutdown handling code will
// segfault trying to handle the error, and the untranslated IDs are strictly better.
T = TfuncWithFallback("en")
TDefault = TfuncWithFallback("en")
translationsDir := "i18n"
if mattermostPath := os.Getenv("MM_SERVER_PATH"); mattermostPath != "" {
translationsDir = filepath.Join(mattermostPath, "i18n")
}
return InitTranslationsWithDir(translationsDir)
}
func InitTranslations(localizationSettings model.LocalizationSettings) error {
settings = localizationSettings
var err error
T, err = GetTranslationsBySystemLocale()
return err
}
func InitTranslationsWithDir(dir string) error {
i18nDirectory, found := fileutils.FindDirRelBinary(dir)
if !found {
return fmt.Errorf(fmt.Sprintf("Unable to find i18n directory at %q", dir))
}
files, _ := ioutil.ReadDir(i18nDirectory)
for _, f := range files {
if filepath.Ext(f.Name()) == ".json" {
filename := f.Name()
locales[strings.Split(filename, ".")[0]] = filepath.Join(i18nDirectory, filename)
if err := i18n.LoadTranslationFile(filepath.Join(i18nDirectory, filename)); err != nil {
return err
}
}
}
return nil
}
func GetTranslationsBySystemLocale() (i18n.TranslateFunc, error) {
locale := *settings.DefaultServerLocale
if _, ok := locales[locale]; !ok {
mlog.Error("Failed to load system translations for", mlog.String("locale", locale), mlog.String("attempting to fall back to default locale", model.DEFAULT_LOCALE))
locale = model.DEFAULT_LOCALE
}
if locales[locale] == "" {
return nil, fmt.Errorf("Failed to load system translations for '%v'", model.DEFAULT_LOCALE)
}
translations := TfuncWithFallback(locale)
if translations == nil {
return nil, fmt.Errorf("Failed to load system translations")
}
mlog.Info("Loaded system translations", mlog.String("for locale", locale), mlog.String("from locale", locales[locale]))
return translations, nil
}
func GetUserTranslations(locale string) i18n.TranslateFunc {
if _, ok := locales[locale]; !ok {
locale = model.DEFAULT_LOCALE
}
translations := TfuncWithFallback(locale)
return translations
}
func GetTranslationsAndLocale(w http.ResponseWriter, r *http.Request) (i18n.TranslateFunc, string) {
// This is for checking against locales like pt_BR or zn_CN
headerLocaleFull := strings.Split(r.Header.Get("Accept-Language"), ",")[0]
// This is for checking against locales like en, es
headerLocale := strings.Split(strings.Split(r.Header.Get("Accept-Language"), ",")[0], "-")[0]
defaultLocale := *settings.DefaultClientLocale
if locales[headerLocaleFull] != "" {
translations := TfuncWithFallback(headerLocaleFull)
return translations, headerLocaleFull
} else if locales[headerLocale] != "" {
translations := TfuncWithFallback(headerLocale)
return translations, headerLocale
} else if locales[defaultLocale] != "" {
translations := TfuncWithFallback(defaultLocale)
return translations, headerLocale
}
translations := TfuncWithFallback(model.DEFAULT_LOCALE)
return translations, model.DEFAULT_LOCALE
}
func GetSupportedLocales() map[string]string {
return locales
}
func TfuncWithFallback(pref string) i18n.TranslateFunc {
t, _ := i18n.Tfunc(pref)
return func(translationID string, args ...interface{}) string {
if translated := t(translationID, args...); translated != translationID {
return translated
}
t, _ := i18n.Tfunc(model.DEFAULT_LOCALE)
return t(translationID, args...)
}
}