Skip to content

Commit 3070c4a

Browse files
committed
Format and remove 10.3.md spaces
1 parent a1ed5d7 commit 3070c4a

File tree

1 file changed

+91
-91
lines changed

1 file changed

+91
-91
lines changed

zh/10.3.md

Lines changed: 91 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -5,103 +5,103 @@
55
在开发一个应用的时候,首先我们要决定是只支持一种语言,还是多种语言,如果要支持多种语言,我们则需要制定一个组织结构,以方便将来更多语言的添加。在此我们设计如下:Locale有关的文件放置在config/locales下,假设你要支持中文和英文,那么你需要在这个文件夹下放置en.json和zh.json。大概的内容如下所示:
66
```json
77

8-
# zh.json
8+
# zh.json
99

10-
{
11-
"zh": {
12-
"submit": "提交",
13-
"create": "创建"
14-
}
10+
{
11+
"zh": {
12+
"submit": "提交",
13+
"create": "创建"
1514
}
15+
}
1616

17-
#en.json
17+
#en.json
1818

19-
{
20-
"en": {
21-
"submit": "Submit",
22-
"create": "Create"
23-
}
19+
{
20+
"en": {
21+
"submit": "Submit",
22+
"create": "Create"
2423
}
24+
}
2525

2626
```
2727
为了支持国际化,在此我们使用了一个国际化相关的包——[go-i18n](https://github.com/astaxie/go-i18n),首先我们向go-i18n包注册config/locales这个目录,以加载所有的locale文件
2828
```Go
2929

30-
Tr:=i18n.NewLocale()
31-
Tr.LoadPath("config/locales")
30+
Tr:=i18n.NewLocale()
31+
Tr.LoadPath("config/locales")
3232

3333
```
3434
这个包使用起来很简单,你可以通过下面的方式进行测试:
3535
```Go
3636

37-
fmt.Println(Tr.Translate("submit"))
38-
//输出Submit
39-
Tr.SetLocale("zh")
40-
fmt.Println(Tr.Translate("submit"))
41-
//输出“递交”
37+
fmt.Println(Tr.Translate("submit"))
38+
//输出Submit
39+
Tr.SetLocale("zh")
40+
fmt.Println(Tr.Translate("submit"))
41+
//输出“递交”
4242
```
4343
## 自动加载本地包
4444
上面我们介绍了如何自动加载自定义语言包,其实go-i18n库已经预加载了很多默认的格式信息,例如时间格式、货币格式,用户可以在自定义配置时改写这些默认配置,请看下面的处理过程:
4545
```Go
4646

47-
//加载默认配置文件,这些文件都放在go-i18n/locales下面
47+
//加载默认配置文件,这些文件都放在go-i18n/locales下面
4848

49-
//文件命名zh.json、en-json、en-US.json等,可以不断的扩展支持更多的语言
49+
//文件命名zh.json、en-json、en-US.json等,可以不断的扩展支持更多的语言
5050

51-
func (il *IL) loadDefaultTranslations(dirPath string) error {
52-
dir, err := os.Open(dirPath)
53-
if err != nil {
54-
return err
55-
}
56-
defer dir.Close()
51+
func (il *IL) loadDefaultTranslations(dirPath string) error {
52+
dir, err := os.Open(dirPath)
53+
if err != nil {
54+
return err
55+
}
56+
defer dir.Close()
5757

58-
names, err := dir.Readdirnames(-1)
58+
names, err := dir.Readdirnames(-1)
59+
if err != nil {
60+
return err
61+
}
62+
63+
for _, name := range names {
64+
fullPath := path.Join(dirPath, name)
65+
66+
fi, err := os.Stat(fullPath)
5967
if err != nil {
6068
return err
6169
}
6270

63-
for _, name := range names {
64-
fullPath := path.Join(dirPath, name)
65-
66-
fi, err := os.Stat(fullPath)
71+
if fi.IsDir() {
72+
if err := il.loadTranslations(fullPath); err != nil {
73+
return err
74+
}
75+
} else if locale := il.matchingLocaleFromFileName(name); locale != "" {
76+
file, err := os.Open(fullPath)
6777
if err != nil {
6878
return err
6979
}
80+
defer file.Close()
7081

71-
if fi.IsDir() {
72-
if err := il.loadTranslations(fullPath); err != nil {
73-
return err
74-
}
75-
} else if locale := il.matchingLocaleFromFileName(name); locale != "" {
76-
file, err := os.Open(fullPath)
77-
if err != nil {
78-
return err
79-
}
80-
defer file.Close()
81-
82-
if err := il.loadTranslation(file, locale); err != nil {
83-
return err
84-
}
82+
if err := il.loadTranslation(file, locale); err != nil {
83+
return err
8584
}
8685
}
87-
88-
return nil
8986
}
9087

88+
return nil
89+
}
90+
9191
```
9292
通过上面的方法加载配置信息到默认的文件,这样我们就可以在我们没有自定义时间信息的时候执行如下的代码获取对应的信息:
9393
```Go
9494

95-
//locale=zh的情况下,执行如下代码:
95+
//locale=zh的情况下,执行如下代码:
9696

97-
fmt.Println(Tr.Time(time.Now()))
98-
//输出:2009年1月08日 星期四 20:37:58 CST
97+
fmt.Println(Tr.Time(time.Now()))
98+
//输出:2009年1月08日 星期四 20:37:58 CST
9999

100-
fmt.Println(Tr.Time(time.Now(),"long"))
101-
//输出:2009年1月08日
100+
fmt.Println(Tr.Time(time.Now(),"long"))
101+
//输出:2009年1月08日
102102

103-
fmt.Println(Tr.Money(11.11))
104-
//输出:¥11.11
103+
fmt.Println(Tr.Money(11.11))
104+
//输出:¥11.11
105105
```
106106
## template mapfunc
107107
上面我们实现了多个语言包的管理和加载,而一些函数的实现是基于逻辑层的,例如:"Tr.Translate"、"Tr.Time"、"Tr.Money"等,虽然我们在逻辑层可以利用这些函数把需要的参数进行转换后在模板层渲染的时候直接输出,但是如果我们想在模版层直接使用这些函数该怎么实现呢?不知你是否还记得,在前面介绍模板的时候说过:Go语言的模板支持自定义模板函数,下面是我们实现的方便操作的mapfunc:
@@ -111,83 +111,83 @@
111111
文本信息调用`Tr.Translate`来实现相应的信息转换,mapFunc的实现如下:
112112
```Go
113113

114-
func I18nT(args ...interface{}) string {
115-
ok := false
116-
var s string
117-
if len(args) == 1 {
118-
s, ok = args[0].(string)
119-
}
120-
if !ok {
121-
s = fmt.Sprint(args...)
122-
}
123-
return Tr.Translate(s)
114+
func I18nT(args ...interface{}) string {
115+
ok := false
116+
var s string
117+
if len(args) == 1 {
118+
s, ok = args[0].(string)
119+
}
120+
if !ok {
121+
s = fmt.Sprint(args...)
124122
}
123+
return Tr.Translate(s)
124+
}
125125

126126
```
127127
注册函数如下:
128128
```Go
129129

130-
t.Funcs(template.FuncMap{"T": I18nT})
130+
t.Funcs(template.FuncMap{"T": I18nT})
131131
```
132132
模板中使用如下:
133133
```Go
134134

135-
{{.V.Submit | T}}
135+
{{.V.Submit | T}}
136136
```
137137

138138
2. 时间日期
139139

140140
时间日期调用`Tr.Time`函数来实现相应的时间转换,mapFunc的实现如下:
141141
```Go
142142

143-
func I18nTimeDate(args ...interface{}) string {
144-
ok := false
145-
var s string
146-
if len(args) == 1 {
147-
s, ok = args[0].(string)
148-
}
149-
if !ok {
150-
s = fmt.Sprint(args...)
151-
}
152-
return Tr.Time(s)
143+
func I18nTimeDate(args ...interface{}) string {
144+
ok := false
145+
var s string
146+
if len(args) == 1 {
147+
s, ok = args[0].(string)
148+
}
149+
if !ok {
150+
s = fmt.Sprint(args...)
153151
}
152+
return Tr.Time(s)
153+
}
154154
```
155155
注册函数如下:
156156
```Go
157157

158-
t.Funcs(template.FuncMap{"TD": I18nTimeDate})
158+
t.Funcs(template.FuncMap{"TD": I18nTimeDate})
159159
```
160160
模板中使用如下:
161161
```Go
162162

163-
{{.V.Now | TD}}
163+
{{.V.Now | TD}}
164164
```
165165
3. 货币信息
166166

167167
货币调用`Tr.Money`函数来实现相应的时间转换,mapFunc的实现如下:
168168
```Go
169169

170-
func I18nMoney(args ...interface{}) string {
171-
ok := false
172-
var s string
173-
if len(args) == 1 {
174-
s, ok = args[0].(string)
175-
}
176-
if !ok {
177-
s = fmt.Sprint(args...)
178-
}
179-
return Tr.Money(s)
170+
func I18nMoney(args ...interface{}) string {
171+
ok := false
172+
var s string
173+
if len(args) == 1 {
174+
s, ok = args[0].(string)
175+
}
176+
if !ok {
177+
s = fmt.Sprint(args...)
180178
}
179+
return Tr.Money(s)
180+
}
181181
```
182182
注册函数如下:
183183
```Go
184184

185-
t.Funcs(template.FuncMap{"M": I18nMoney})
185+
t.Funcs(template.FuncMap{"M": I18nMoney})
186186
```
187187
模板中使用如下:
188188
```Go
189189

190-
{{.V.Money | M}}
190+
{{.V.Money | M}}
191191
```
192192
## 总结
193193
通过这小节我们知道了如何实现一个多语言包的Web应用,通过自定义语言包我们可以方便的实现多语言,而且通过配置文件能够非常方便的扩充多语言,默认情况下,go-i18n会自定加载一些公共的配置信息,例如时间、货币等,我们就可以非常方便的使用,同时为了支持在模板中使用这些函数,也实现了相应的模板函数,这样就允许我们在开发Web应用的时候直接在模板中通过pipeline的方式来操作多语言包。

0 commit comments

Comments
 (0)