标签:多语言 i18n iplas
背景
应泰方要求,运营系统、网上商城以及移动端服务平台等项目都要做国际化,支持英文、泰文等多国语言。故研讨国际化方案对项目进行国际化改造。
1.后端
关键:使用java.util.Locale类判断地区,处理国际化差异
项目 | 解决方案 |
---|---|
静态配置文件 | 处理成zh_CN.properties(中文需要处理ASCII编码格式)和th_TH.properties版本,使用java.util.ResourceBundle根据地区读取 |
错误提示 | 中文翻译成泰文,处理成中文和泰文2个错误枚举类,根据地区选择一个枚举类 |
日期 | 使用java.util.DateFormat类及其子类SimpleDateFormat根据地区处理 |
数字、货币、百分比 | 使用java.util.NumberFormat类根据地区处理 |
2.前端
关键:i18n.properties
项目 | 解决方案 |
---|---|
配置文件 | 配置*_i18n.properties 国际字典,用以多国语言翻译 |
静态文字 | 使用*i18n国际化插件匹配字典重新赋值(预估工作量相当大) |
动态数据中的文字 | 后端处理后发送到前端 |
样式 | 不同语言文案长度不一样造成的样式错乱,对样式要做适配性修改(预估工作量相当大),先统一处理英文版本,再适配其它语言 |
图片 | 例如帮助指引等,替换泰文版新图 |
第三方服务SDK | 运营系统中暂时没有 |
数字、货币单位 | 使用阿拉伯数字,货币单位使用฿,要增加货币格式化工具函数处理 |
日期、时间 | 使用泰国当地时间 |
国际化插件选择
前端处理国际化的插件总类繁多,不同的框架各有不同。比如vue有vue-i18n,jquery有 jquery-i18n,构建层面有i18n-webpack-plugin等等。且不同国际化插件语法各不相同,学习起来有一定的时间成本,维护起来也不方便。对于公司来说,项目肯定不止一个,使用的技术框架也不尽相同,如果能有一个通用、易用、好用的的国际化插件统一使用维护那是再好不过了。
既然是通用,便要支持各种技术框架,类似vue-i18n这些配合指定框架的插件便不大适用了。当然,直接vue + vue-i18n这样的固定搭配也是可以的。网传较多的通用国际化插件jQuery.i18n.properties,试用了一下,不是说不好用不能用,只是它依赖JQuery,在页面加载中如果有多处页面引用JQuery,会有JQuery重新加载导致jQuery.i18n被覆盖不能正常试用的情况,这就不大理想了。而且,可能有一些公司项目就不引用JQuery插件,总不能为此强迫人家吧。后来查找发现,di18n-translate插件也可以满足需求,查看了源码并不依赖JQuery等其它插件,纯原生语法编写。使用也是简单。
di18n-translate
介绍
di18n-translate是基于原生js进行开发的一个函数js,不依赖于某一个构建工具或者某一个框架,即使是原生html也可以使用,在兼容性方面是比较能满足我们的要求的。详情可查看https://github.com/CommanderXL/di18n-translate
安装
npm install di18n-translate
使用demo
const DI18n = require('di18n-translate')
const di18n = new DI18n({
locale: 'en', // 语言环境
isReplace: false, // 是否开启运行时功能(适用于没有使用任何构建工具开发流程)
messages: { // 语言映射表
en: {
你好: 'Hello, {xl}'
},
zh: {
你好: '你好, {xl}'
}
}
})
di18n有2个翻译方法: html
// 带参数
di18n.$t('你好', {person: 'xl'})
// 输出 Hello, xl
字符串拼接的dom中使用t()标识需要翻译的字段,用法如下:
let tpl = '' +
'' +
'$t("你好")
' +
''
let str = di18n.$html(tpl)
// 字符串替换后输出字符串str:
Hello
// 最后再将这个dom字符串传入到页面当中去
document.querySelector('.box-wrapper').innerHTML = str
运营系统国际化改造实战
相信现在除了最传统的web前端项目外,大多数的前端开发都采用组件化的模式,比如小编公司使用的polymer、Vue框架,都封装有大量的组件方便开发使用。在进行国际化时候,为尽可能的的不改变开发模式且减少工作量,将国际化翻译的东西封装在组件的最底层,在组件内部进行改造。
以运营系统为例:
- 地址栏添加language=‘zh‘属性用以切换区分语言,如http://127.0.0.1/demo?language=‘zh‘
- 配置语言字典,实例化di18n函数对象。(方法写在o-base-behavior.html中,方便调用)
const di18n = new DI18n({
locale: LOCALE,
isReplace: true, // 开启运行时
messages: {
en: En,
zh: Zh
}
})
English.js
const En = {
搜索: 'search',
重置: 'reset',
...
}
Chinese.js
const En = {
搜索: '搜索',
重置: ' 重置',
...
}
o-base-behaviors.html
h-crud-search.html
[[i18n('搜索')]]
test.html
en
zh
注意事项: 在组件里面使用i18n方法时,一定要记得引入OBaseBehavior这个公共方法实例化对象,不然i18n会转换失败。
Vue项目使用di18n-translate
先进行全局注册:
main.js
window.LOCALE = 'en'
const language = localStorage.getItem('language') // 进行语言切换的时候用到
if(language) {
window.LOCALE = language
}
const DI18n = require('di18n-translate')
const di18n = new DI18n({
locale: LOCALE, // 语言环境
isReplace: false, // 是否进行替换(适用于没有使用任何构建工具开发流程)
messages: { // 语言映射表
en: {
你好: 'Hello'
},
zh: {
你好: '你好'
}
}
})
Vue.prototype.di18n = di18n
Vue.prototype.i18n = function (name) { //封装一个全局方法,可以在任何vue文件里面进行字符串替换
const temp = di18n.$t(name) // 封装翻译方法
if (temp && temp !== 'undefined') {
return di18n.$t(name)
}else {
return name
}
}
18n.vue
{{title}}
{{i18n('你好')}}
总结
组件化的代码在底层组件的基础上进行国际化,可以最大程度上减少工作量。从调研结果来看,使用di18n-translate,是可行的。