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 560
/
i18n.go
123 lines (104 loc) · 3.17 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
package i18n
import (
"errors"
"fmt"
"io/ioutil"
"os"
"strings"
"path"
"github.com/leonelquinteros/gotext"
)
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 {
if t.Locale == nil {
return fmt.Sprintf(msgid, vars...)
}
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 {
if t.Locale == nil {
return fmt.Sprintf(msgidPlural, vars...)
}
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...))
}