我们项目中的国际化

时间:2020-03-05 18:37:27  来源:igfitidea点击:

我们如何在实际工作中实现国际化(i18n)?

在阅读了Joel的著名文章"绝对是每个软件开发人员的绝对最低知识"之后,我对使软件跨文化产生了兴趣,这绝对是关于Unicode和字符集的肯定知识(无借口!)。但是,除了确保在可能的情况下使用Unicode字符串之外,我还不能在实际项目中利用此功能。但是,使所有字符串都成为Unicode并确保我们了解使用的所有工作都采用什么编码,这只是i18n冰山一角。

到目前为止,我所做的所有工作都已由一组受控制的美国英语国家的人使用,或者说i18n只是在我们将该项目付诸实施之前我们没有时间进行工作。因此,我正在寻找人们关于使软件在实际项目中更加本地化的任何提示或者战争故事。

解决方案:

我为以前使用.NET的雇主设计了一个项目,并且使用了内置的.resx格式。我们基本上有一个文件,它在.resx文件中包含所有翻译,然后是多个具有不同翻译的文件。这样的结果是,我们必须非常努力地确保应用程序中所有可见的字符串都存储在.resx中,并且每当更改一个字符串时,我们都必须更新所支持的所有语言。

如果我们懒惰并且不通知翻译负责人,或者在不通过本地化系统的情况下嵌入字符串,那么以后尝试对其进行修复将是一场噩梦。同样,如果本地化是事后的想法,将很难实施。最重要的是,如果我们没有将所有可见的字符串都存储在标准位置的外部,那么将很难找到所有需要本地化的字符串。

另请注意,非常严格地避免直接连接可见字符串,例如

String message = "The " + item + " is on sale!";

相反,我们必须使用类似

String message = String.Format("The {0} is on sale!", item);

原因是不同的语言通常会以不同的顺序排列单词,并且直接串联字符串将需要修复新的构建,但是如果我们使用了如上所述的某种字符串替换机制,则可以修改.resx文件(或者任何本地化版本)我们使用的文件)以表示需要对单词进行重新排序的特定语言。

一些有趣的事情:

  • 有一个PHP和MySQL应用程序,可以很好地兼容德语和法语,但是现在需要支持俄语和中文。我认为我将其移至.net,因为我认为PHP的Unicode支持不是很好。当然,玩转utf8_de / encode或者mbstring-functions很有趣。几乎和晚上弗雷迪·克格(Freddy Krger)拜访我们一样有趣...
  • 意识到某些语言比其他语言更为详尽。德语通常比英语更冗长,并且看到德语版本如何破坏了用户界面,因为分配的空间太小并不有趣。一些产品因其创新的解决方法而闻名,例如Oblivion的" Schw.Tr.d.Le.En.W"。令人难忘:-)
  • 玩弄日期格式,woohoo!是的,实际上世界上有些人在中间使用日期格式。试图找出2008年7月2日的含义是一件很有趣的事情,只是因为某些用户可能认为可能是7月2日。。。但是,同样,在池塘边的家伙可能也相信那些将它们放在7月2日的用户。中间一个月:-P,尤其是因为英语,7月2日听起来比7月2日好很多,这不一定适用于其他语言(例如,德语,我们从不会说Juli 2,但总是Zweiter Juli)。我尽可能使用2008-02-07. 显然,这意味着2月7日并且可以正确排序,但是dd / mm vs. mm / dd可能是一个非常棘手的问题。
  • 有趣的事,数字格式! 10.000,50对10,000.50对10,000,50对10,000,50 ...这是我目前最大的噩梦,必须支持多元文化环境,但无法可靠地知道用户使用哪种数字格式将使用。
  • 正式或者非正式的。在某种语言中,有两种与人打交道的方式,一种是正式的方式,另一种是非正式的方式。用英语,我们只说" You",但是用德语,我们必须在正式的" Sie"和非正式的" Du"之间做出选择,法语Tu / Vous也是一样。通常,选择正式方式是一个安全的选择,但这很容易被忽略。
  • 日历。在欧洲,一周的第一天是星期一,而在美国,则是星期日。日历小部件很好。向欧洲用户显示左侧带有星期日和右侧带有星期六的日历不是很好,这会使他们感到困惑。

我今天早上只是在听斯科特·汉塞尔曼(Scott Hanselman)的播客,他在那儿谈论国际化,尤其是真正棘手的事情,例如土耳其语(等于4)和泰国语。另外,Jeff Atwood也发表了一篇文章:

已经有一段时间了,所以这并不全面。

字符集

Unicode很棒,但是我们不能无视其他字符集。 Windows XP(英语)上的默认字符集是Cp1252. 在网络上,我们不知道浏览器将向我们发送什么信息(尽管希望容器可以处理大部分操作)。而且,无论我们使用的是什么实现方式中的错误,都不要感到惊讶。当字符集在计算机之间移动时,它们可以与文件名进行有趣的交互。

翻译字符串

一般来说,翻译员不是编码员。如果我们将源文件发送给翻译者,他们将破坏该文件。字符串应提取到资源文件中(例如Java中的属性文件或者Visual C ++中的资源DLL)。应该为翻译人员提供难以破解的文件,以及不能让其破坏的工具。

翻译人员不知道字符串在哪里来自产品。没有上下文就很难翻译字符串。如果我们不提供指导,翻译质量将会受到影响。

关于上下文,我们可能会多次看到相同的字符串" foo",并认为将UI中的所有实例都指向同一资源会更有效。这是一个坏主意。在某些语言中,单词可能对上下文非常敏感。

翻译字符串会花费金钱。如果发布产品的新版本,则恢复旧版本是有意义的。有工具可以从旧资源文件中恢复字符串。

字符串连接和字符串的手动操作应最小化。在适当的地方使用格式功能。

译者需要能够修改热键。 Ctrl + P用英文打印;德国人使用Ctrl + D。

如果翻译过程要求有人随时手动剪切和粘贴字符串,那么我们会遇到麻烦。

日期,时间,日历,货币,数字格式,时区

这些因国家而异。逗号可以用来表示小数位。时间可能以24小时表示法。并非每个人都使用公历。我们也需要明确。如果我们注意在网站上将日期显示为MM / DD / YYYY(美国)和DD / MM / YYYY(英国),则除非用户知道我们已经这样做,否则日期会模棱两可。

特别是货币

类库中提供的Locale函数将为我们提供本地货币符号,但我们不能仅将磅(英镑)或者欧元符号粘贴在以美元表示价格的值之前。

使用者介面

布局应该是动态的。不仅字符串翻译时的长度可能加倍,而且整个UI可能需要反转(希伯来语;阿拉伯语),以便控件从右到左运行。那是我们到达亚洲之前的事情。

翻译前测试

  • 对代码进行静态分析以查找问题。至少要利用IDE内置的工具。 (Eclipse用户可以转到窗口>首选项> Java>编译器>错误/警告,并检查未外部化的字符串。)
  • 通过模拟翻译进行冒烟测试。解析资源文件并用伪翻译版本替换字符串并不困难,伪版本将长度加倍并插入时髦的字符。我们无需使用某种语言即可使用外部操作系统。现代系统应允许我们以具有翻译后的字符串和外部语言环境的外部用户身份登录。如果我们熟悉操作系统,则可以在不知道该语言的任何单词的情况下弄清楚该做什么。
  • 键盘映射和字符集引用非常有用。
  • 虚拟化在这里非常有用。

非技术问题

有时,我们必须对文化差异敏感(可能会冒犯或者不理解)。我们经常看到的一个错误是使用标志作为选择网站语言或者地理位置的视觉提示。除非我们希望软件在全球政治中宣布立场,否则这是个坏主意。如果我们是法国人,并且提供了带有圣乔治旗的英语选项(英格兰的旗帜是在白场上的红叉),这可能会导致许多英语使用者感到困惑,因为假设其他语言和国家也会遇到类似的问题。需要对图标进行文化相关性审查。竖起大拇指或者绿色勾号是什么意思?语言应该相对中立,以一种特定的方式来称呼用户在一个地区是可以接受的,但在另一个地区则被认为是粗鲁的。

资源

C ++和Java程序员可能会发现ICU网站很有用:http://www.icu-project.org/

我使用的一个网站拥有一种翻译方法,所有者称其为" Wiki +机器翻译"。这是一个基于社区的站点,因此显然与公司的需求不同。

http://blog.bookmooch.com/2007/09/23/how-bookmooch-does-its-translations/

我认为从事国际化工作的每个人都应该熟悉通用语言环境数据存储库,该库现在是Unicode的子项目:

通用语言环境数据存储库

这些人正在努力建立各种国际问题的标准资源:货币,地名,大量物品。鉴于这个项目的存在,任何维护自己的核心本地数据的项目都是非常棒的,恕我直言。

除了前面的所有技巧外,请记住,在i18n中,不仅仅是将单词更改为与其他语言等效,尤其是对于从右到左书写的非拉丁语言字母(韩语,阿拉伯语),因此整个UI必须与

  • 项目1
  • 项目2
  • 项目3

一定是

阿拉伯文字1-

阿拉伯文字2-

阿拉伯文字3-

(反向的项目符号列表似乎不起作用:P)

如果系统一旦用户更改了所使用的语言就必须动态地应用更改,那么这可能是UI的噩梦。

另一个非常困难的事情是测试不同的语言,不仅是为了单词的正确性,而且由于像韩语这样的语言通常具有更大的字体字体,这可能导致特定于语言的错误(例如按钮上的" SAVE"文本大于按钮本身以显示某种语言)。

没有人提到的一件事是带有一些警惕性的字符串,如"单位将在5天后到达"或者"星期一发生了什么"。其中5和星期一将根据州而改变。将它们分成两部分并连接起来不是一个好主意。只有一个不同的部分和良好的文档,我们可能会不满意,而两个不同的部分将有些语言更喜欢更改它们的顺序。

有趣的发现之一:斜体和粗体文本makrup不适用于CJK(中文/日文/韩文)字符。它们只是变得不可读。 (好吧,我之前也无法真正阅读它们,但特别是粗体会造成墨水斑点)

我建议使用诸如99translations.com之类的内容来维护翻译。否则,我们将无法分辨每种语言的最新翻译版本。

另一个挑战是接受用户的输入。在许多情况下,可通过操作系统提供的输入处理(例如Windows中的IME)来减轻这种负担,该输入处理可与常见的文本小部件透明地一起使用,但是此功能将无法满足所有可能的需求。