考虑下面的需求:
- 开发一个支持多国语言的应用,需支持中文(zh_CN)和英文(en_US)两种语言
- 默认情况下,根据浏览器的语言配置,显示相应的文本,包括 javascript 提示信息
- 如果浏览器配置为 zh 开头的中文系语言(如 zh_TW),则显示中文(zh_CN),其他语言都显示为英文
- 中文为默认语言,对于 en_US 中未定义的文本,则显示为中文
- 用户可以通过个性设置配置自己的首选语言
Grails 虽然提供了通用的国际化解决方案,但是对于上述需求完全无法满足,因此,我们在 BroToolkit/BroFWK 中对其进行了扩展和改造,以满足上述需求。
在应用 Config.groovy 中可以配置系统支持的语言和语言映射关系,按照上面的需求,配置如下:
/** 系统支持的i18n语言 */
bropen.toolkit.i18n.supported = ["zh_CN", "en_US"]
/** 语言不在上面列表中时的映射关系 */
bropen.toolkit.i18n.mapping = ["zh_CN": ["zh*"], "en_US":["*"]]
解释如下:
- i18n.supported:
- 配置可支持的语言列表,默认为 ["zh_CN"];
- 根据需求1,这里添加 en_US;
- 考虑需求4,将 zh_CN 设置为第一条作为默认语言
- i18n.mapping:
- 配置语言的映射关系,默认为空 [:];
- 根据需求3,配置以 zh 为前缀的所有语言都映射到 zh_CN,其他语言都映射到 en_US
注意这里的通配符 * 仅支持作为语言后缀。
为了加深理解,再举例如下:
- 应用支持英文、中文两种语言,但是英文为系统默认语言
- 所有 zh 为前缀的语言都映射到 zh_CN 上,而其他语言都采用默认语言 en_US
/** 系统支持的i18n语言 */
bropen.toolkit.i18n.supported = ["en_US", "zh_CN"]
/** 语言不在上面列表中时的映射关系 */
bropen.toolkit.i18n.mapping = ["zh_CN": ["zh*"]]
语言文件包括 grails-app/i18n/*.properties 文件,以及 grails-app/assets/javascript/i18n/*.js 文件,前者用于后台API、视图标签标签调用(参考Internationalization),后者用于 javascript API 调用(参考JavaScript的国际化支持)。
用户个性设置 fwk.locale (即常量 bropen.framework.Constants.UP_LOCALE)可以用来设置个人的首选语言,在个性配置视图 _editProfile_broFramework.gsp 中定义了设置界面。
<g:select class="up-locale" name="profiles.${Constants.UP_LOCALE}" from="${GrailsUtils.getConfig('bropen.toolkit.i18n.supported')}" value="${profiles[Constants.UP_LOCALE]}" />
<script>$j(".up-locale option:first").val('')</script>
Grails 提供了一系列 API 来获得 properties 文件中定义的文本,如常用的 message 标签(视图、控制器中都可以用),以及预定义的 spring bean messageSource。
除此以外,我们还提供了几个工具 API 来计算当前语言和获取多语言文本,详细请参考API手册:
- GrailsUtils.message( String code, List args = null, String defaultMsg = "" ):同 Grails 的 message API,但可以在任何地方调用
- GrailsUtils.errorMessages( Object bean ):将 bean.errors 中的错误对象转换成错误消息列表
- GrailsUtils.messageLang( String lang ):计算当前使用的国际化语言
- GrailsUtils.messageLocale( String lang )
在 JavaScript 的国际化支持中,我们除了提供 API m 来获得 js 文件中定义的文本外,还可以通过 page.lang 和 page.country 获得当前语言,如 { lang: "zh", country:"CN" }。
更多关于 BroToolkit/BroFWK 中的国际化支持和问题,可以点击下面标签的“国际化”。