i18n:国际化。 L10N:本地化。
国际化:就是根据特定的locale信息,提取与之相应的字符串或其他一些东西。
1、如何确定locale。2、如何保存与locale相关的字符串或其他信息。3、如何根据Locale提取字符串和其他相应的信息。
Locale是一组描述世界上某一特定区域文本格式和语言习惯的设置的集合。
Locale通常由三个部分组成:
第一部分是一个强制性的表示语言的缩写。
第二部分是跟在有一个下划线之后,是一个可选的国家说明符,列如en_US表示美国英语,en_UK表示英国英语。
第三部分跟在一个句点之后是可选的字符集说明符,例如”zh_CN.gb2312“表示中国使用gb2312字符集
GO语言默认采用“UTF-8”编码集
$ locale -a
设置Locale的办法之一是在应用运行的时候采用域名分级的方式。
.com表示英文站,.cn表示中文站。
if r.Hsot == "www.asta.com" { i18n.SetLocale("en") } else if r.Host == "www.asta.cn" { i18n.SetLocale("zh-CN") }
目前最常用的方式是URL里面带上参数,例如www.asta.com/hellow?locale=zh
Accept-Language
客户端请求的时候在HTTP头信息里面有Accept-Language。
AL := r.Header.Get("Accept-Language") if AL == "en" { i18n.SetLocale("en") } else if AL == "zh-CN" { i18n.SetLocale("zh-CN") }
另一种根据客户端来设定地区的就是用户访问的IP,根据相应的IP库,就可以得到对应的IP地区。
根据用户输入的信息保存到账号相关的profile中。
建立需要的语言相应的MAP来维护一个key-value的关系,在输出之前按需从适合的map中去获取相应的文本。
1、时区问题。2、格式问题。
en["time_zone"]="America/Chicago" cn["time_zone"]="Asia/Shanghai" loc,_:=time.LoadLocation(msg(lang,"time_zone")) t:=time.Now() t = t.In(loc) fmt.Println(t.Format(time.RFC3339))
en["money"] ="USD %d" cn["money"] ="¥%d元" fmt.Println(money_format(msg(lang,"date_format"),100)) func money_format(fomate string,money int64) string{ return fmt.Sprintf(fomate,money) }
使用一个国际化相关的包——go-i18n,首先我们向go-i18n包注册config/locales这个目录,以加载所有的Locale文件。
Tr := i18n.NewLocale() Tr.LoadPath("config/locales")
fmt.Println(Tr.Translate("submit")) //输出Submit Tr.SetLocale("zh") fmt.Println(Tr.Translate("submit")) //输出“提交”
// 加载默认配置文件,这些文件都放在 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
1、文本信息。文本信息调用Tr.Translate来实现相应的信息转换
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}}
2、时间日期
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}}
3、货币信息
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}}