6.6 KiB
10.2 Localized Resources
The previous section described how to set locales. After the locale has been set, we then need to address the problem of storing the information corresponding to specific locales. This information can include: textual content, time and date, currency values , pictures, specific files and other view resources. In Go, all of this contextual information is stored in JSON format on our backend, to be called upon and injected into our views when users from specific regions visit our website. For example, English and Chinese content would be stored in en.json and zh-CN.json files, respectively.
Localized textual content
Plain text is the most common way of representing information in web applications, and the bulk of your localized content will likely take this form. The goal is to provide textual content that is both idiomatic to regional expressions and feels natural for foreign users of your site. One solution is to create a nested map of locales, native language strings and their international counterparts. When clients request pages with some textual content, we first check their desired locale, then retrieve the corresponding strings from the appropriate map. The following snippet is a simple example of this process:
package main
import "fmt"
var locales map[string]map[string]string
func main() {
locales = make(map[string]map[string]string, 2)
en := make(map[string]string, 10)
en["pea"] = "pea"
en["bean"] = "bean"
locales["en"] = en
cn := make(map[string]string, 10)
cn["pea"] = "豌豆"
cn["bean"] = "毛豆"
locales["zh-CN"] = cn
lang := "zh-CN"
fmt.Println(msg(lang, "pea"))
fmt.Println(msg(lang, "bean"))
}
func msg(locale, key string) string {
if v, ok := locales[locale]; ok {
if v2, ok := v[key]; ok {
return v2
}
}
return ""
}
The above example sets up maps of translated strings for different locales (in this case, the Chinese and English locales). We map our cn translations to the same English language keys so that we can reconstruct our English text message in Chinese. If we wanted to switch our text to any other locale we may have implemented, it'd be a simple matter of setting one lang variable.
Simple key-value substitutions can sometimes be inadequate for our needs. For example, "I am 30 years old", Chinese expression "I am 30 years old," and where 30 is a variable, how to do it? This time, we can combine fmt.Printf function to achieve, see the following code:
en["how old"] = "I am %d years old"
cn["how old"] = "我今年%d岁了"
fmt.Printf(msg(lang, "how old"), 30)
The above example code is only to demonstrate the internal implementations, but the actual data is stored in the JSON inside, so we can json.Unmarshal to populate the data for the corresponding map.
Localized date and time
Because the relationship between time zones, the same time, in different regions, which means that is not the same, but because of the relationship between Locale and time formats are not the same, for example, Chinese environment may be displayed:
October 24, 2012 Wednesday 23:11 minutes and 13 seconds CST, while in the English environment may show: Wed Oct 24 23:11:13 CST 2012. That which we need to address two points:
- time zones
- formatting issues
$GOROOT/lib/time/package/timeinfo.zip contain locale corresponds to the time zone definition, in order to obtain a time corresponding to the current locale, we should first use time.LoadLocation (name string) Get the region corresponding to the locale, such as Asia/Shanghai or America/Chicago corresponding to the time zone information, and then use this information to call the time.Now time object obtained collaborate to get the final time. Detailed Look at the following example (this example uses the example above, some of the variables):
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))
We can handle text format similar way to solve the problem of time format, for example as follows:
en["date_format"]="%Y-%m-%d %H:%M:%S"
cn["date_format"]="%Y年%m月%d日 %H时%M分%S秒"
fmt.Println(date(msg(lang,"date_format"),t))
func date(fomate string,t time.Time) string{
year, month, day = t.Date()
hour, min, sec = t.Clock()
//Parsing the corresponding %Y%m%d%H%M%S and then return information
//%Y replaced by 2012
//%m replaced by 10
//%d replaced by 24
}
Localized currency value
Various regions of the currency is not the same, is also treated with a date about the details see the following code:
en["money"] ="USD %d"
cn["money"] ="¥%d元"
fmt.Println(date(msg(lang,"date_format"),100))
func money_format(fomate string,money int64) string{
return fmt.Sprintf(fomate,money)
}
Localization views and resources
We may use Locale to show different views that contain different images, css, js and other static resources. So how to deal with these information? First we shall locale to organize file information, see the following file directory Arrangement:
views
|--en //English Templates
|--images //store picture information
|--js //JS files
|--css //CSS files
index.tpl //User Home
login.tpl //Log Home
|--zh-CN //Chinese Templates
|--images
|--js
|--css
index.tpl
login.tpl
With this directory structure we can render to realize where this code:
s1, _ := template.ParseFiles("views" + lang + "index.tpl")
VV.Lang = lang
s1.Execute(os.Stdout, VV)
As for the inside of the resources inside the index.tpl set as follows:
// js file
<script type="text/javascript" src="views/{{.VV.Lang}}/js/jquery/jquery-1.8.0.min.js"></script>
// css file
<link href="views/{{.VV.Lang}}/css/bootstrap-responsive.min.css" rel="stylesheet">
// Picture files
<img src="views/{{.VV.Lang}}/images/btn.png">
With this view, and the way to localize the resources, we can easily be expanded.
Summary
This section describes how to use and store local resources, sometimes through the conversion function to achieve, sometimes through lang to set up, but eventually through key-value way to store Locale corresponding data when needed remove the corresponding Locale information, if it is a text message directly to the output, if it is the date and time or money, you need to pass fmt.Printf or other formatting function to deal with, and for different views and resources Locale is the most simple, as long as increase in the path which can be achieved lang.
Links
- Directory
- Previous section: Time zone
- Next section: [International sites