From f6b42217c90fb6107f8f2dfe6b85ae66a4978a4c Mon Sep 17 00:00:00 2001 From: xiemengjun Date: Tue, 30 Oct 2012 21:36:46 +0800 Subject: [PATCH] =?UTF-8?q?review=20=E7=AC=AC=E5=8D=81=E7=AB=A0=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 10.2.md | 24 ++++++++++++------------ 10.3.md | 11 ++++++----- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/10.2.md b/10.2.md index 15fee775..af6a67f8 100644 --- a/10.2.md +++ b/10.2.md @@ -1,7 +1,7 @@ # 10.2 本地化资源 前面小节我们介绍了如何设置Locale,设置好Locale之后我们需要解决的问题就是如何存储相应的Locale对应的信息呢?这里面的信息包括:文本信息、时间和日期、货币值、图片、包含文件以及视图等资源。那么接下来我们讲对这些信息一一进行介绍,Go语言中我们把这些格式信息存储在JSON中,然后通过合适的方式展现出来。(接下来以中文和英文两种语言对比举例,存储格式文件en.json和zh-CN.json) ## 本地化文本消息 -文本信息是我们编写Web应用中最长用到的,也是本地化资源中最多的信息,你想要以适合本地的语言显示文本信息,那么就需要建立相应的map来维护一个key-value的关系,在打印消息之前从map中去获取相应的字符串,例如下面这个例如,一个包含英文和中文的食品名称的简单的map,以及一个从该map中抽取单词的函数。 +本信息是编写Web应用中最常用到的,也是本地化资源中最多的信息,想要以适合本地语言的方式来显示文本信息,可行的一种方案是:建立需要的语言相应的map来维护一个key-value的关系,在输出之前按需从适合的map中去获取相应的文本,如下是一个简单的示例: package main @@ -34,24 +34,24 @@ } -上面实现了简单的不同locale的文本翻译,实现了中文和英文对于同一个key显示不同的语言,上面实现了中文语言的文本消息,如果想切换到英文版本,只需要把lang设置问en即可。 +上面示例演示了不同locale的文本翻译,实现了中文和英文对于同一个key显示不同语言的实现,上面实现了中文的文本消息,如果想切换到英文版本,只需要把lang设置为en即可。 -但是有些时候并不是简单的key-value就能实现所有的文本翻译的,例如"I am 30 years old",中文表达是"我今年30岁了",而这个30是一个变量,这个时候我们可以结合`fmt.Printf`函数来实现,请看下面的代码: +有些时候仅是key-value替换是不能满足需要的,例如"I am 30 years old",中文表达是"我今年30岁了",而此处的30是一个变量,该怎么办呢?这个时候,我们可以结合`fmt.Printf`函数来实现,请看下面的代码: en["how old"] ="I am %d years old" cn["how old"] ="我今年%d岁了" fmt.Printf(msg(lang, "how old"), 30) -上面的示例代码主要是为了演示我们内部实现的思路,其实最后数据是存储在JSON里面的,map我们可以通过`json.Unmarshal`获取对应的数据。 +上面的示例代码仅用以演示内部的实现方案,而实际数据是存储在JSON里面的,所以我们可以通过`json.Unmarshal`来为相应的map填充数据。 ## 本地化日期和时间 -时间和日期对于不同的地区会显示不同的时间点,而且相应的显示时间格式也是不同的,例如中文环境下可能显示:`2012年10月24日 星期三 23时11分13秒 CST`,而在英文环境下可能显示:`Wed Oct 24 23:11:13 CST 2012`。这里面我们需要解决两点: +因为时区的关系,同一时刻,在不同的地区,表示是不一样的,而且因为Locale的关系,时间格式也不尽相同,例如中文环境下可能显示:`2012年10月24日 星期三 23时11分13秒 CST`,而在英文环境下可能显示:`Wed Oct 24 23:11:13 CST 2012`。这里面我们需要解决两点: 1. 时区问题 2. 格式问题 -时区问题我们可以通过`time.Now`返回当前locale的时间,但是我们可以通过`time.LoadLocation(name string)`获取相应地区的时区,如果中文地区,那么`name=Asia/Shanghai`,如果在美国那么可以设置`name=America/Chicago`,你可以在`$GOROOT/lib/time`包中找到time.zip,里面有每个地区的时区定义。详细的请看下面的例子: +$GOROOT/lib/time包中的timeinfo.zip含有locale对应的时区的定义,为了获得对应于当前locale的时间,我们应首先使用`time.LoadLocation(name string)`获取相应于地区的locale,比如`Asia/Shanghai`或`America/Chicago`对应的时区信息,然后再利用此信息与调用`time.Now`获得的Time对象协作来获得最终的时间。详细的请看下面的例子(该例子采用上面例子的一些变量): en["time_zone"]="America/Chicago" cn["time_zone"]="Asia/Shanghai" @@ -61,7 +61,7 @@ t = t.In(loc) fmt.Println(t.Format(time.RFC3339)) -格式问题我们可以通过类似上面文本信息的方式解决这个问题,就如上面刚开始显示的时间格式一样,中文和英文的显示信息完全不同,那我们就可以通过如下方式来实现 +我们可以通过类似处理文本格式的方式来解决时间格式的问题,举例如下: en["date_format"]="%Y-%m-%d %H:%M:%S" cn["date_format"]="%Y年%m月%d日 %H时%M分%S秒" @@ -78,7 +78,7 @@ } ## 本地化货币值 -各个地区的货币表示也不一样,我们想要根据不同的Locale显示不同的货币金额需要实现如上时间格式的处理函数,详细的实现请看下面代码: +各个地区的货币表示也不一样,处理方式也与日期差不多,细节请看下面代码: en["money"] ="USD %d" cn["money"] ="¥%d元" @@ -91,7 +91,7 @@ ## 本地化视图和资源 -我们在展现不同Locale的时候可能会根据不同的Locale采用不同的视图,这些视图里面包含不同的图片、css、js等各种静态资源。那么我们如何来处理这些信息呢?首先我们需要组织对应的locale文件信息,请看下面的文件目录安排: +我们可能会根据Locale的不同来展示视图,这些视图包含不同的图片、css、js等各种静态资源。那么应如何来处理这些信息呢?首先我们应按locale来组织文件信息,请看下面的文件目录安排: views |--en //英文模板 @@ -107,7 +107,7 @@ index.tpl login.tpl -有了这个文件安排之后我们就可以在渲染的地方这样来实现代码 +有了这个目录结构后我们就可以在渲染的地方这样来实现代码: s1, _ := template.ParseFiles("views"+lang+"index.tpl") @@ -123,10 +123,10 @@ //图片文件 -这样我们在本地化视图以及资源的时候采用这种方式就可以很容易的进行扩展了。 +采用这种方式来本地化视图以及资源时,我们就可以很容易的进行扩展了。 ## 总结 -本小节介绍了如何使用存储本地资源,本地资源有些需要通过转换函数,有些通过lang设置,但是最后都是通过key-value的方式存储了相应的Locale对应数据,然后通过转换函数通过key读取出来相应的Locale信息,如果是文本信息就直接输出了,如果是时间日期或者货币需要结合`fmt.Printf`函数的处理才能转换成正确的信息展示,而对于不同Locale的视图和资源是最简单的,只要在路径里面增加lang就可以实现了。 +本小节介绍了如何使用及存储本地资源,有时需要通过转换函数来实现,有时通过lang来设置,但是最终都是通过key-value的方式来存储Locale对应的数据,在需要时取出相应于Locale的信息后,如果是文本信息就直接输出,如果是时间日期或者货币,则需要先通过`fmt.Printf`或其他格式化函数来处理,而对于不同Locale的视图和资源则是最简单的,只要在路径里面增加lang就可以实现了。 ## links * [目录]() diff --git a/10.3.md b/10.3.md index 419b6c3e..416e80d4 100644 --- a/10.3.md +++ b/10.3.md @@ -1,7 +1,7 @@ # 10.3 国际化站点 前面小节介绍了如何处理本地化资源,即Locale一个相应的配置文件,那么如果处理多个的本地化资源呢?而对于一些我们经常用到的例如:简单的文本翻译、时间日期、数字等如果处理呢?本小节将一一解决这些问题。 ## 管理多个本地包 -在我们开发一个应用的时候,首先我们应该知道这个Web应用要支持多少个语言,例如首先这个Web应用需要支持中文和英文,也许以后会支持其他语言,但是结构已经有了,所以扩展非常容易。那么我们设计如下:Locale文件夹在config/locales下,假设你要支持中文和英语,那么你需要在这个文件夹下放置en.json和zh.json。大概的内容如下所示: +在开发一个应用的时候,首先我们要决定是只支持一种语言,还是多种语言,如果要支持多种语言,我们则需要制定一个组织结构,以方便将来更多语言的添加。在此我们设计如下:Locale有关的文件放置在config/locales下,假设你要支持中文和英文,那么你需要在这个文件夹下放置en.json和zh.json。大概的内容如下所示: # zh.json @@ -21,12 +21,12 @@ } } -然后调用go-i18n包里面注册一下这个目录,这样Go会加载config/locales目录下的locale文件: +为了支持国际化,在此我们使用了一个国际化相关的包——go-i18n(https://github.com/astaxie/go-i18n),首先我们向go-i18n包注册config/locales这个目录,以加载所有的locale文件 Tr:=i18n.NewLocale() Tr.LoadPath("config/locales") -使用很简单,你可以通过下面的方式进行测试: +这个包使用起来很简单,你可以通过下面的方式进行测试: fmt.Println(Tr.Translate("submit")) //输出Submit @@ -35,7 +35,8 @@ //输出“递交” ## 自动加载本地包 -上面我们介绍了多个自定义语言包的自动加载,那么在我们加载的同时,其实go-i18n库会自动帮你加载一些定义的格式信息,例如时间格式、货币格式。所以在go-i18n包里面已经有了很多语言的时间格式、货币格式等定义,其实在调用NewLocale的时候这些默认的配置已经加载好了,用户可以继续在自己的定义配置中复写这些配置,请看下面的处理过程: +上面我们介绍了如何自动加载自定义语言包,其实go-i18n库已经预加载了很多默认的格式信息,例如时间格式、货币格式,用户可以在自定义配置时改写这些默认配置,请看下面的处理过程: + //加载默认配置文件,这些文件都放在go-i18n/locales下面 @@ -95,7 +96,7 @@ //输出:¥11.11 ## template mapfunc -上面我们实现了多个语言包的管理和加载,而一些函数的实现也是基于逻辑层的,例如:"Tr.Translate"、"Tr.Time"、"Tr.Money"等函数,虽然利用这些函数我们再逻辑层可以把需要的参数进行转换然后在模板层渲染的时候直接输出,但是如果我们想在模版层直接使用这些函数该怎么实现呢?我们前面在介绍模板这小节的时候介绍过,Go语言的模板支持自定义模板函数,下面是我们实现的方便操作的mapfunc: +上面我们实现了多个语言包的管理和加载,而一些函数的实现是基于逻辑层的,例如:"Tr.Translate"、"Tr.Time"、"Tr.Money"等,虽然我们在逻辑层可以利用这些函数把需要的参数进行转换后在模板层渲染的时候直接输出,但是如果我们想在模版层直接使用这些函数该怎么实现呢?不知你是否还记得,在前面介绍模板的时候说过:Go语言的模板支持自定义模板函数,下面是我们实现的方便操作的mapfunc: 1. 文本信息