5.6 KiB
10.3 国际化站点
前面小节介绍了如何处理本地化资源,即Locale一个相应的配置文件,那么如果处理多个的本地化资源呢?而对于一些我们经常用到的例如:简单的文本翻译、时间日期、数字等如果处理呢?本小节将一一解决这些问题。
管理多个本地包
在我们开发一个应用的时候,首先我们应该知道这个Web应用要支持多少个语言,例如首先这个Web应用需要支持中文和英文,也许以后会支持其他语言,但是结构已经有了,所以扩展非常容易。那么我们设计如下:Locale文件夹在config/locales下,假设你要支持中文和英语,那么你需要在这个文件夹下放置en.json和zh.json。大概的内容如下所示:
# zh.json
{
"zh": {
"submit": "提交",
"create": "创建"
}
}
#en.json
{
"en": {
"submit": "Submit",
"create": "Create"
}
}
然后调用go-i18n包里面注册一下这个目录,这样Go会加载config/locales目录下的locale文件:
Tr:=i18n.NewLocale()
Tr.LoadPath("config/locales")
使用很简单,你可以通过下面的方式进行测试:
fmt.Println(Tr.Translate("submit"))
//输出Submit
Tr.SetLocale("zn")
fmt.Println(Tr.Translate("submit"))
//输出“递交”
自动加载本地包
上面我们介绍了多个自定义语言包的自动加载,那么在我们加载的同时,其实go-i18n库会自动帮你加载一些定义的格式信息,例如时间格式、货币格式。所以在go-i18n包里面已经有了很多语言的时间格式、货币格式等定义,其实在调用NewLocale的时候这些默认的配置已经加载好了,用户可以继续在自己的定义配置中复写这些配置,请看下面的处理过程:
//加载默认配置文件,这些文件都放在go-i18n/locales下面
//文件命名zh.json、en-json、en-US.json等,可以不断的扩展支持更多的语言
func (il *IL) loadDefaultTranslations(dirPath string) error {
dir, err := os.Open(dirPath)
if err != nil {
return err
}
defer dir.Close()
names, err := dir.Readdirnames(-1)
if err != nil {
return err
}
for _, name := range names {
fullPath := path.Join(dirPath, name)
fi, err := os.Stat(fullPath)
if err != nil {
return err
}
if fi.IsDir() {
if err := il.loadTranslations(fullPath); err != nil {
return err
}
} else if locale := il.matchingLocaleFromFileName(name); locale != "" {
file, err := os.Open(fullPath)
if err != nil {
return err
}
defer file.Close()
if err := il.loadTranslation(file, locale); err != nil {
return err
}
}
}
return nil
}
通过上面的方法加载配置信息到默认的文件,这样我们就可以在我们没有自定义时间信息的时候执行如下的代码获取对应的信息:
//locale=zh的情况下,执行如下代码:
fmt.Println(Tr.Time(time.Now()))
//输出:2009年1月08日 星期四 20:37:58 CST
fmt.Println(Tr.Time(time.Now(),"long"))
//输出:2009年1月08日
fmt.Println(Tr.Money(11.11))
//输出:¥11.11
template mapfunc
上面我们实现了多个语言包的管理和加载,而一些函数的实现也是基于逻辑层的,例如:"Tr.Translate"、"Tr.Time"、"Tr.Money"等函数,虽然利用这些函数我们再逻辑层可以把需要的参数进行转换然后在模板层渲染的时候直接输出,但是如果我们想在模版层直接使用这些函数该怎么实现呢?我们前面在介绍模板这小节的时候介绍过,Go语言的模板支持自定义模板函数,下面是我们实现的方便操作的mapfunc:
-
文本信息
文本信息调用
Tr.Translate来实现相应的信息转换,mapFunc的实现如下:func I18nT(args ...interface{}) string { ok := false var s string if len(args) == 1 { s, ok = args[0].(string) } if !ok { s = fmt.Sprint(args...) } return Tr.Translate(s) }注册函数如下:
t.Funcs(template.FuncMap{"T": I18nT})模板中使用如下:
{{.V.Submit | T}} -
时间日期
时间日期调用
Tr.Time函数来实现相应的时间转换,mapFunc的实现如下:func I18nTimeDate(args ...interface{}) string { ok := false var s string if len(args) == 1 { s, ok = args[0].(string) } if !ok { s = fmt.Sprint(args...) } return Tr.Time(s) }注册函数如下:
t.Funcs(template.FuncMap{"TD": I18nTimeDate})模板中使用如下:
{{.V.Now | TD}} -
货币信息
货币调用
Tr.Money函数来实现相应的时间转换,mapFunc的实现如下:func I18nMoney(args ...interface{}) string { ok := false var s string if len(args) == 1 { s, ok = args[0].(string) } if !ok { s = fmt.Sprint(args...) } return Tr.Money(s) }注册函数如下:
t.Funcs(template.FuncMap{"M": I18nMoney})模板中使用如下:
{{.V.Money | M}}
总结
通过这小节我们知道了如何实现一个多语言包的Web应用,通过自定义语言包我们可以方便的实现多语言,而且通过配置文件能够非常方便的扩充多语言,默认情况下,go-i18n会自定加载一些公共的配置信息,例如时间、货币等,我们就可以非常方便的使用,同时为了支持在模板中使用这些函数,也实现了相应的模板函数,这样就允许我们在开发Web应用的时候直接在模板中通过pipeline的方式来操作多语言包。
links
LastModified
Id