## 什么是Locale
Locale是一组描述世界上某一特定区域文本格式和语言习惯的设置的集合。locale名通常由三个部分组成:第一部分,是一个强制性的,表示语言的缩写,例如"en"表示英文或"zh"表示中文。第二部分,跟在一个下划线之后,是一个可选的国家说明符,用于区分讲同一种语言的不同国家,例如"en_US"表示美国英语,而"en_UK"表示英国英语。最后一部分,跟在一个句点之后,是可选的字符集说明符,例如"zh_CN.gb2312"表示中国使用gb2312字符集。
GO语言默认采用"UTF-8"编码集,所以我们实现i18n时不考虑第三部分,接下来我们都采用locale描述的前面两部分来作为i18n标准的locale名。
> 在Linux和Solaris系统中可以通过`locale -a`命令列举所有支持的地区名,读者可以看到这些地区名的命名规范。对于BSD等系统,没有locale命令,但是地区信息存储在/usr/share/locale中。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.1.md#设置locale)设置Locale
有了上面对locale的定义,那么我们就需要根据用户的信息(访问信息、个人信息、访问域名等)来设置与之相关的locale,我们可以通过如下几种方式来设置用户的locale。
### [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.1.md#通过域名设置locale)通过域名设置Locale
设置Locale的办法这一就是在应用运行的时候采用域名分级的方式,例如,我们采用www.asta.com当做我们的英文站(默认站),而把域名www.asta.cn当做中文站。这样通过在应用里面设置域名和相应的locale的对应关系,就可以设置好地区。这样处理有几点好处:
* 通过URL就可以很明显的识别
* 用户可以通过域名很直观的知道将访问那种语言的站点
* 在Go程序中实现非常的简单方便,通过一个map就可以实现
* 有利于搜索引擎抓取,能够提高站点的SEO
我们可以通过下面的代码来实现域名的对应locale:
~~~
if r.Host == "www.asta.com" {
i18n.SetLocale("en")
} else if r.Host == "www.asta.cn" {
i18n.SetLocale("zh-CN")
} else if r.Host == "www.asta.tw" {
i18n.SetLocale("zh-TW")
}
~~~
当然除了整域名设置地区之外,我们还可以通过子域名来设置地区,例如"en.asta.com"表示英文站点,"cn.asta.com"表示中文站点。实现代码如下所示:
~~~
prefix := strings.Split(r.Host,".")
if prefix[0] == "en" {
i18n.SetLocale("en")
} else if prefix[0] == "cn" {
i18n.SetLocale("zh-CN")
} else if prefix[0] == "tw" {
i18n.SetLocale("zh-TW")
}
~~~
通过域名设置Locale有如上所示的优点,但是我们一般开发Web应用的时候不会采用这种方式,因为首先域名成本比较高,开发一个Locale就需要一个域名,而且往往统一名称的域名不一定能申请的到,其次我们不愿意为每个站点去本地化一个配置,而更多的是采用url后面带参数的方式,请看下面的介绍。
### [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.1.md#从域名参数设置locale)从域名参数设置Locale
目前最常用的设置Locale的方式是在URL里面带上参数,例如www.asta.com/hello?locale=zh或者www.asta.com/zh/hello。这样我们就可以设置地区:`i18n.SetLocale(params["locale"])`。
这种设置方式几乎拥有前面讲的通过域名设置Locale的所有优点,它采用RESTful的方式,以使得我们不需要增加额外的方法来处理。但是这种方式需要在每一个的link里面增加相应的参数locale,这也许有点复杂而且有时候甚至相当的繁琐。不过我们可以写一个通用的函数url,让所有的link地址都通过这个函数来生成,然后在这个函数里面增加`locale=params["locale"]`参数来缓解一下。
也许我们希望URL地址看上去更加的RESTful一点,例如:www.asta.com/en/books(英文站点)和www.asta.com/zh/books(中文站点),这种方式的URL更加有利于SEO,而且对于用户也比较友好,能够通过URL直观的知道访问的站点。那么这样的URL地址可以通过router来获取locale(参考REST小节里面介绍的router插件实现):
~~~
mux.Get("/:locale/books", listbook)
~~~
### [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.1.md#从客户端设置地区)从客户端设置地区
在一些特殊的情况下,我们需要根据客户端的信息而不是通过URL来设置Locale,这些信息可能来自于客户端设置的喜好语言(浏览器中设置),用户的IP地址,用户在注册的时候填写的所在地信息等。这种方式比较适合Web为基础的应用。
* Accept-Language
客户端请求的时候在HTTP头信息里面有`Accept-Language`,一般的客户端都会设置该信息,下面是Go语言实现的一个简单的根据`Accept-Language`实现设置地区的代码:
~~~
AL := r.Header.Get("Accept-Language")
if AL == "en" {
i18n.SetLocale("en")
} else if AL == "zh-CN" {
i18n.SetLocale("zh-CN")
} else if AL == "zh-TW" {
i18n.SetLocale("zh-TW")
}
~~~
当然在实际应用中,可能需要更加严格的判断来进行设置地区
* IP地址
另一种根据客户端来设定地区就是用户访问的IP,我们根据相应的IP库,对应访问的IP到地区,目前全球比较常用的就是GeoIP Lite Country这个库。这种设置地区的机制非常简单,我们只需要根据IP数据库查询用户的IP然后返回国家地区,根据返回的结果设置对应的地区。
* 用户profile
当然你也可以让用户根据你提供的下拉菜单或者别的什么方式的设置相应的locale,然后我们将用户输入的信息,保存到与它帐号相关的profile中,当用户再次登陆的时候把这个设置复写到locale设置中,这样就可以保证该用户每次访问都是基于自己先前设置的locale来获得页面。
## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/10.1.md#总结)总结
通过上面的介绍可知,设置Locale可以有很多种方式,我们应该根据需求的不同来选择不同的设置Locale的方法,以让用户能以它最熟悉的方式,获得我们提供的服务,提高应用的用户友好性。
- 第一章 Go环境配置
- 1.1 Go安装
- 1.2 GOPATH 与工作空间
- 1.3 Go 命令
- 1.4 Go开发工具
- 1.5 小结
- 第二章 Go语言基础
- 2.1 你好,Go
- 2.2 Go基础
- 2.3 流程和函数
- 2.4 struct类型
- 2.5 面向对象
- 2.6 interface
- 2.7 并发
- 2.8 总结
- 第三章 Web基础
- 3.1 Web工作方式
- 3.2 Go搭建一个Web服务器
- 3.3 Go如何使得Web工作
- 3.4 Go的http包详解
- 3.5 小结
- 第四章 表单
- 4.1 处理表单的输入
- 4.2 验证表单的输入
- 4.3 预防跨站脚本
- 4.4 防止多次递交表单
- 4.5 处理文件上传
- 4.6 小结
- 第五章 访问数据库
- 5.1 database/sql接口
- 5.2 使用MySQL数据库
- 5.3 使用SQLite数据库
- 5.4 使用PostgreSQL数据库
- 5.5 使用beedb库进行ORM开发
- 5.6 NOSQL数据库操作
- 5.7 小结
- 第六章 session和数据存储
- 6.1 session和cookie
- 6.2 Go如何使用session
- 6.3 session存储
- 6.4 预防session劫持
- 6.5 小结
- 第七章 文本处理
- 7.1 XML处理
- 7.2 JSON处理
- 7.3 正则处理
- 7.4 模板处理
- 7.5 文件操作
- 7.6 字符串处理
- 7.7 小结
- 第八章 Web服务
- 8.1 Socket编程
- 8.2 WebSocket
- 8.3 REST
- 8.4 RPC
- 8.5 小结
- 第九章 安全与加密
- 9.1 预防CSRF攻击
- 9.2 确保输入过滤
- 9.3 避免XSS攻击
- 9.4 避免SQL注入
- 9.5 存储密码
- 9.6 加密和解密数据
- 9.7 小结
- 第十章 国际化和本地化
- 10.1 设置默认地区
- 10.2 本地化资源
- 10.3 国际化站点
- 10.4 小结
- 第十一章 错误处理,调试和测试
- 11.1 错误处理
- 11.2 使用GDB调试
- 11.3 Go怎么写测试用例
- 11.4 小结
- 第十二章 部署与维护
- 12.1 应用日志
- 12.2 网站错误处理
- 12.3 应用部署
- 12.4 备份和恢复
- 12.5 小结
- 第十三章 如何设计一个Web框架
- 13.1 项目规划
- 13.2 自定义路由器设计
- 13.3 controller设计
- 13.4 日志和配置设计
- 13.5 实现博客的增删改
- 13.6 小结
- 第十四章 扩展Web框架
- 14.1 静态文件支持
- 14.2 Session支持
- 14.3 表单及验证支持
- 14.4 用户认证
- 14.5 多语言支持
- 14.6 pprof支持
- 14.7 小结
- 附录A 参考资料