Tom*_*Tom 3 globalization translation internationalization
我将为Node.js(服务器端Javascript)实现这个,但这个问题是关于如何解决这个问题的一般方法.
有许多平台支持国际申请的翻译.
例如,Zend的翻译适配器的工作方式如下:
printf($translate->_("Today is the %1\$s") . "\n", date("d.m.Y"));
Run Code Online (Sandbox Code Playgroud)
Android的系统为每种语言使用strings.xml文件,并使用与Zend相同的概念.
这些适用于大多数西方语言.但是,许多非西方语言需要不同的单词顺序,或者甚至从右到左而不是从左到右的方向读取.
因此,在上述翻译调用中定义的指定顺序对于"外来"语言可能是无效的.
这让我想到了一个问题,如何设计适合任何语言的翻译系统/适配器?
实际上很难直接回答这个问题.这里有很多用例.如果我要设计这样的系统,我会记住这些事情:
1.翻译后可能需要重新命令句子(你已经提到了这个).这就是我们使用{1},{2}等编号占位符和格式化消息的一些方法的原因.
2.有不少语言有多个复数形式.也就是说,如果消息包含一些数字,则取决于数量,它将以不同的方式进行翻译.例如:
英语:已发现1病毒| 已发现2种病毒 已发现5种病毒
波兰语:Znaleziono 1 wirusa | Znaleziono 2 wirusy | Znaleziono5wirusów
这不容易处理,但我真的很喜欢GetText这样做的方式(有一些表达式将决定使用什么形式,以及支持多种形式).
3.此类库的用户可能希望拥有命名占位符(请参阅I18n标记中的前一个问题),例如"这是$ {name}中$ {name}的消息"并使用它,例如:
var formatted ='这是$ {name}的$ {name}消息.格式('location = Warsaw','name =Paweł');
虽然这会引起一些i18n问题,但我很确定它可以在JavaScript中完成(尽管你传递命名参数(也就是参数)的方式可能需要不同.
4. Java倾向于在MessageFormat.format()方法中格式化Number和特定语言环境的日期.这不是理想的行为,它几乎没有问题,特别是在JavaScript中.嗯,首先你需要知道的是,当前用户的Locale是什么.如果你这样做,是否容易?好吧,不.有很多可能的日期格式 - Java将它们枚举为:full,long,medium,short和default.不幸的是,在格式化过程中没有区别 - 总是会使用AFAIR短片.当然,可以将他的格式传递给占位符,就像这样(AFAIR):{0,date,yyyy-MM-dd}.这带来了另一个问题:翻译人员总是必须提供格式.这很容易出错.相反,我会使用默认模式格式化(如果没有给出其他信息)并允许传递模式名称:{0,date,long}.
对于数字,它可以是任何东西:货币,百分比或简单数值.您还需要支持区别,例如:{0,货币,符号:$,long},{0,百分比},{0,数字,长}.猜猜我的意思并不容易,但对于大数字你可能想要使用分组分隔符(1,000,000.00 $),让我们称它为长格式,而有时你想打印这样的数字:1234.这不是一件容易的事.
5. .Net具有用户界面文化(CurrentUICulture)和格式化文化(CurrentCulture)的概念.首先用于确定用户界面消息的适当语言,而第二个用于格式化(数字,日期,货币等).
6.不同的语言倾向于使用不同的排序顺序,即使是同一种语言也可以使用两种(或更多种)不同的语言.我不确定它是否符合范围,但至少要注意这一点.
7.可能需要支持不同的字符编码(并且可能是).但是,您可能希望将Encoding for resources文件限制为UTF-8.它不会涵盖所有可能的字符(例如参见GB18030),但它很接近.
......?
好吧,我确信我忘记了一些重要的事情,因为你要接近的任务是巨大的.我对Node.js知之甚少(就像目前支持的那样).
编辑
8.当然我忘了提到随着软件的发展,只有少数用户界面消息发生变化,因此需要合并旧的翻译(在L10n术语中称为Leveraging).通常使用某种翻译记忆库软件(例如POEdit,GetText文件格式编辑器内置了这样的功能).TM软件通常仅支持某些文件格式,因此坚持使用现有格式而不是创建自己的格式是个好主意.这可能意味着从列表中删除一些功能......