6.3 KiB
10.3 International sites
The previous section explained how to deal with localized resources, namely by using locale configuration files. So what can we do if we need to deal with multiple localized resources like text translations, times and dates, numbers, etc? This section will address these issues one by one.
Managing multiple locale packages
In the development of an application, often the first thing you need to do is to decide whether or not you want to support more than one language. If you do decide to support multiple languages, you'll need to develop an organizational structure to facilitate the process of adding more languages in the future. One way we can do this is to put all our related locale files together in a config/locales directory, or something of the like. Let's suppose you want to support both Chinese and English. In this case, you'd be placing both the en.json and zh.json locale files into the aforementioned folder. Their contents would probably look something like the following:
# zh.json
{
"zh": {
"submit": "提交",
"create": "创建"
}
}
#en.json
{
"en": {
"submit": "Submit",
"create": "Create"
}
}
We decided to use some 3rd party Go packages to help us internationalize our web applications. In the case of go-i18n ( A more advanced i18n package can be found here ), we first have to register our config/locales directory to load all of our locale files:
Tr := i18n.NewLocale()
Tr.LoadPath("config/locales")
This package is simple to use. We can test that it works like so:
fmt.Println(Tr.Translate("submit"))
//Output "submit"
Tr.SetLocale("zn")
fmt.Println(Tr.Translate("submit"))
//Outputs "递交"
Automatically load local package
We've just described how to automatically load custom language packs. In fact, the go-i18n library comes pre-loaded with a bunch of default formatting information such as time and currency formats. These default configurations can be overridden and customized by users to suit their needs:
//Load the default configuration files, which are placed below `go-i18n/locales`
//File naming zh.json, en-json, en-US.json etc., can be continuously extended to support more languages
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
}
Using the above method to load configuration information to the default file, so that we can customize the time we do not have information when executed the following code to obtain the corresponding information:
//locale = zh, execute the following code:
fmt.Println(Tr.Time(time.Now()))
//Output: 2009年1月08日 星期四 20:37:58 CST
fmt.Println(Tr.Time(time.Now(),"long"))
//Output: 2009年1月08日
fmt.Println(Tr.Money(11.11))
//Output: ¥11.11
Template mapfunc
Above we achieve a number of language packs and load management, and some function implementation is based on the logical layer, for example: "Tr.Translate", "Tr.Time", "Tr.Money" and so on, while we at the logical level You can use these functions to the parameters required for conversion when rendering the template layer output directly, but if we want to use them directly in the template layer functions that how to achieve it? I do not know if you remember, at the time said earlier template: Go language template support custom template function, the following is our implementation to facilitate the operation of mapfunc:
1 text information
Text information call Tr.Translate to achieve the appropriate information conversion, mapFunc is implemented as follows:
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)
}
Registration function is as follows:
t.Funcs(template.FuncMap{"T": I18nT})
Using the following template:
{{.V.Submit | T}}
- The date and time
Date and time to call Tr.Time function to achieve the appropriate time for a change, mapFunc is implemented as follows:
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)
}
Registration function is as follows:
t.Funcs(template.FuncMap{"TD": I18nTimeDate})
Using the following template:
{{.V.Now | TD}}
3 Currency Information
Currency called Tr.Money function to achieve the appropriate time for a change, mapFunc is implemented as follows:
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)
}
Registration function is as follows:
t.Funcs(template.FuncMap{"M": I18nMoney})
Using the following template:
{{.V.Money | M}}
Summary
Through this section we know how to implement a multi-language package for Web applications, through a custom language packs that we can facilitate the realization of multi-language, but also through the configuration file can be very convenient to expand multi-language, by default, go-i18n will be self- fixed load some common configuration information, such as time, money, etc., we can be very convenient to use, and in order to support the use of these functions in the template, but also to achieve the appropriate template functions, thus allowing us to develop Web applications in the time directly in the template the way through the pipeline operate multiple language packs.
Links
- Directory
- Previous section: Localized resources
- Next section: Summary