This repository has been archived by the owner on Jan 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 558
/
i18n.go
130 lines (109 loc) · 3.31 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
package i18n
import (
"errors"
"fmt"
"io/ioutil"
"os"
"strings"
"path"
"github.com/leonelquinteros/gotext"
)
const (
defaultLanguage = "default"
defaultDomain = "acsengine"
defaultLocalDir = "translations"
defaultMessageDir = "LC_MESSAGES"
)
var supportedTranslations = map[string]bool{
defaultLanguage: true,
"en_US": true,
"zh_CN": true,
}
func loadSystemLanguage() string {
language := os.Getenv("LANG")
if language == "" {
return defaultLanguage
}
// Posix locale name usually has the ll_CC.encoding syntax.
parts := strings.Split(language, ".")
if len(parts) == 0 {
return defaultLanguage
}
if _, ok := supportedTranslations[parts[0]]; ok {
return parts[0]
}
return defaultLanguage
}
// LoadTranslations loads translation files and sets the locale to
// the system locale. It should be called by the main program.
func LoadTranslations() (*gotext.Locale, error) {
lang := loadSystemLanguage()
SetLanguage(lang)
dir := path.Join(defaultLocalDir, lang, defaultMessageDir)
translationFiles := []string{
path.Join(dir, fmt.Sprintf("%s.mo", defaultDomain)),
path.Join(dir, fmt.Sprintf("%s.po", defaultDomain)),
}
if _, err := os.Stat(dir); os.IsNotExist(err) {
if err := os.MkdirAll(dir, 0700); err != nil {
return nil, err
}
}
for _, file := range translationFiles {
if _, err := os.Stat(file); os.IsNotExist(err) {
data, err := Asset(file)
if err != nil {
return nil, err
}
err = ioutil.WriteFile(file, data, 0600)
if err != nil {
return nil, err
}
}
}
locale := gotext.NewLocale(defaultLocalDir, lang)
Initialize(locale)
return locale, nil
}
// Initialize is the translation initialization function shared by the main program and package.
func Initialize(locale *gotext.Locale) error {
if locale == nil {
return fmt.Errorf("Initialize expected locale but got nil")
}
locale.AddDomain(defaultDomain)
return nil
}
// SetLanguage sets the program's current locale. If the language is not
// supported, then the default locale is used.
func SetLanguage(language string) {
if _, ok := supportedTranslations[language]; ok {
gotext.SetLanguage(language)
return
}
gotext.SetLanguage(defaultLanguage)
}
// GetLanguage queries the program's current locale.
func GetLanguage() string {
return gotext.GetLanguage()
}
// Translator is a wrapper over gotext's Locale and provides interface to
// translate text string and produce translated error
type Translator struct {
Locale *gotext.Locale
}
// T translates a text string, based on GNU's gettext library.
func (t *Translator) T(msgid string, vars ...interface{}) string {
return t.Locale.GetD(defaultDomain, msgid, vars...)
}
// NT translates a text string into the appropriate plural form, based on GNU's gettext library.
func (t *Translator) NT(msgid, msgidPlural string, n int, vars ...interface{}) string {
return t.Locale.GetND(defaultDomain, msgid, msgidPlural, n, vars...)
}
// Errorf produces an error with a translated error string.
func (t *Translator) Errorf(msgid string, vars ...interface{}) error {
return errors.New(t.T(msgid, vars...))
}
// NErrorf produces an error with a translated error string in the appropriate plural form.
func (t *Translator) NErrorf(msgid, msgidPlural string, n int, vars ...interface{}) error {
return errors.New(t.NT(msgid, msgidPlural, n, vars...))
}