Files
build-web-application-with-…/10.3.md
2012-10-29 17:56:45 +08:00

5.6 KiB
Raw Blame History

10.3 国际化站点

前面小节介绍了如何处理本地化资源即Locale一个相应的配置文件那么如果处理多个的本地化资源呢而对于一些我们经常用到的例如简单的文本翻译、时间日期、数字等如果处理呢本小节将一一解决这些问题。

管理多个本地包

在我们开发一个应用的时候首先我们应该知道这个Web应用要支持多少个语言例如首先这个Web应用需要支持中文和英文也许以后会支持其他语言但是结构已经有了所以扩展非常容易。那么我们设计如下Locale文件夹在config/locales下假设你要支持中文和英语那么你需要在这个文件夹下放置en.json和zh.json。大概的内容如下所示

# zh.json

{
"zh": {
    "submit": "提交",
    "create": "创建"
	}
}

#en.json

{
"en": {
    "submit": "Submit",
    "create": "Create"
	}
}

然后调用go-i18n包里面注册一下这个目录这样Go会加载config/locales目录下的locale文件

Tr:=i18n.NewLocale()	
Tr.LoadPath("config/locales")

使用很简单,你可以通过下面的方式进行测试:

fmt.Println(Tr.Translate("submit"))
//输出Submit
Tr.SetLocale("zn")
fmt.Println(Tr.Translate("submit"))
//输出“递交”

自动加载本地包

上面我们介绍了多个自定义语言包的自动加载那么在我们加载的同时其实go-i18n库会自动帮你加载一些定义的格式信息例如时间格式、货币格式。所以在go-i18n包里面已经有了很多语言的时间格式、货币格式等定义其实在调用NewLocale的时候这些默认的配置已经加载好了用户可以继续在自己的定义配置中复写这些配置请看下面的处理过程

//加载默认配置文件这些文件都放在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

template mapfunc

上面我们实现了多个语言包的管理和加载,而一些函数的实现也是基于逻辑层的,例如:"Tr.Translate"、"Tr.Time"、"Tr.Money"等函数虽然利用这些函数我们再逻辑层可以把需要的参数进行转换然后在模板层渲染的时候直接输出但是如果我们想在模版层直接使用这些函数该怎么实现呢我们前面在介绍模板这小节的时候介绍过Go语言的模板支持自定义模板函数下面是我们实现的方便操作的mapfunc

  1. 文本信息

    文本信息调用Tr.Translate来实现相应的信息转换mapFunc的实现如下

     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. 时间日期

    时间日期调用Tr.Time函数来实现相应的时间转换mapFunc的实现如下

     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. 货币信息

    货币调用Tr.Money函数来实现相应的时间转换mapFunc的实现如下

     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}}
    

总结

通过这小节我们知道了如何实现一个多语言包的Web应用通过自定义语言包我们可以方便的实现多语言而且通过配置文件能够非常方便的扩充多语言默认情况下go-i18n会自定加载一些公共的配置信息例如时间、货币等我们就可以非常方便的使用同时为了支持在模板中使用这些函数也实现了相应的模板函数这样就允许我们在开发Web应用的时候直接在模板中通过pipeline的方式来操作多语言包。

LastModified

  • Id