概述
背景
1.新的海外业务起来,但是未完全成熟,需要不长期的多语言版本支持
2.同一个应用统一页面需要提供不同语言翻译
3.目前只是提供文案上的翻译,不提供或少量结构上的变化
思考
1.webx不在维护范围内,想东webx代码难,而且可能影响面比较大,所以排除webx代码变更,而是从工程层面入手
2.考虑到工期,不能作系统化重构,但是希望预留扩展;
问题分解
多语言的判别模板的多语言化动态提示的多语言化
js代码的多语言化java代码的多语言化
多语言的判别
用户自主选择服务器自主识别
用户自主选择即埋点,即将不同语言的URL埋在页面,由用户自己选择,通过记录用户sessionId和语言的关系来传递用户语言信息,至于这个信息要放到cookie或者服务器端,基于扩展性建议放到服务器端;
服务器自主识别即通过http协议的 Accept-Language头来识别具体的语言。http 1.1协议(RFC2616)中规定Accept-Language的格式如下:
Accept-Language = "Accept-Language" ":" 1#( language-range [ ";" "q" "=" qvalue ] ) language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )可以根据q以及lang-region来判断客户端设置的语言,而该头信息是用户使用软件最熟悉语言,可以理解为用户的第一语言;
对比两种方式第二种剥夺了用户的选择权,举各场景一个中国的高端用户就是选择英语版本的chrome,但是其比较熟悉的语言是中文,这种用户就无法选择;
因此很多网站其实是把两种方案结合起来使用,默认给出一个语言判断,再可以提供链接给用户选择,在99%以上的情况都不需要用户处理,只有极少量用户可以自己选择;
模板的多语言化
阿里系大部分的web端代码都是webx框架,页面的结构都采用jsp、velocity或freemarker,本质上都是模板这些模板包含页面的主题框架样式以及js的引用;
考虑到模板代码的里面比较混杂,但是整体结构又比较稳定,因此可以分析不同语言的模板,分离方式如下:
filename_lang-region.vm
通过lang-region来区分不同语言版本,模板匹配方式如下:
filename_lang-region.vm -> filename_lang.vm -> filename.vm
这样可以直接分离不同的模板
动态提示的多语言化
动态提示大部分都是java代码中,但是这里要单独拎出的原因是笔者认为这部分代码是可以自成一体;我们可以对返回结果作不同的编码,比如采用enum(枚举实现);
通过不同的枚举以及当前用户选择语言区域来判断具体提示的内容;笔者已经实现这部分功能可以参考笔者的代码库(https://programmer-tools.googlecode.com),这样编写代码过程中只需要关注enum code,在功能编写完成后再将不同语言的提供通过配置文件填写上去
js代码的多语言化
在富客户端的影响下,越来越多的程序处理使用js来简化服务器端处理,处理方式主要有几块:越界判断提示、动态图层显示;
越界判断提示有些直接通过代码逻辑写入到js文件中,有些通过后端ajax获取文案;后者不需要js处理,前者需要
动态图层显示一般采用见图层放入到m模板,通过控制变量作显示和隐藏;
基于以上,个人考虑如下:
1.分离js中语言逻辑和文案提示
2.对于引入的文案提示内容采用动态渲染具体文案的URL,vm模板作
java代码的多语言化
这个主要是screen、action代码如何做到将多语言版本的vm整合起来,考虑到webx代码结构,可以通过<renderTemplate />作为切入点,自己实现renderI18NTemplate,实现里面的String getScreenTemplate(String target),String getLayoutTemplate(String target)方法,将多语言功能加入到其中,当然还有其他点,可以通过修改mappingRuleService.getMappedName实现来根本解决。