国际化的devise考虑
我已经阅读了Joel有关Unicode的文章,我觉得从字符集的angular度来看,我至less有一个基本的国际化的把握。 除了阅读这个问题之外 ,我还在devise考虑方面做了一些自己的国际化研究,但是我不禁怀疑那里有更多我不知道或者不知道的东西不知道问。
我学到的一些东西:
- 一些语言从右向左阅读,而不是从左向右阅读。
- 日历,date,时间,货币和数字以不同的语言显示。
- devise应该足够灵活,以容纳更多的文本,因为一些语言比其他语言更详细。
- 当涉及到语义时,不要将图标或颜色视为理所当然,因为这可能因文化而异。
- 地理术语因语言而异。
我在哪里:
- 我的devise足够灵活,可以容纳更多的文字。
- 我会自动翻译每个string,包括错误消息和帮助对话框。
- 我还没有到达需要显示时间,货币或数字单位的地步,但我很快就会到达这个地步,需要开发一个解决scheme。
- 我正在使用UTF-8字符集。
- 我的菜单和应用程序中的各种列表按字母顺序排列,便于阅读。
- 我有一个标签parsing器,通过筛选出停用词来提取标签。 停用词表是语言特定的,可以换出。
我想更多地了解:
- 我正在开发一个可下载的PHP Web应用程序,所以任何关于PHP的具体build议将不胜感激。 我已经开发了自己的框架,并且对此时使用其他框架不感兴趣。
- 我对非西方语言知之甚less。 上面没有提到的是否需要考虑具体的考虑因素? 另外,PHP的数组sorting函数如何处理非西方字符?
- 有没有在实践中经历过的具体问题? 我正在看GUI和应用程序代码本身。
- 有关使用date和时间显示的具体build议? 根据地区或语言是否有分类?
- 我看到很多项目和网站让他们的社区为他们的应用程序和内容提供翻译。 你是否推荐这个,有什么好的策略来确保你有一个好的翻译?
- 这个问题基本上是我所了解的国际化的程度。 我不知道,我不知道我应该进一步研究?
编辑 :我添加了赏金,因为我想从经验中有更多的现实世界的例子。
我们的游戏Gemsweeper已被翻译成8种不同的语言。 在这个过程中我学到了一些东西:
-
如果翻译者给予单个句子来翻译,确保他知道每个句子被使用的上下文,否则他可能会提供一个可能的翻译,但不是你所指的翻译。 像Babelfish这样的工具翻译时不了解上下文,这就是为什么结果通常很糟糕。 试着把英文翻译成德文和德文,然后你就会明白我的意思了。
-
由于相同的原因,应该翻译的句子不能分成不同的部分。 这是因为你需要维护上下文(见前面的观点),因为某些语言可能在句子的开头或结尾处有variables。 使用占位符而不是分解句子。 例如,而不是
“这是我们15步教程的一步”
写下类似于:
“这是我们15步教程的第一步”
并以编程方式replace占位符。
-
不要指望翻译是有趣或创造性的。 他通常没有足够的动力去做,除非你写出特定的文本段落并付给他额外的费用。 例如,如果您的语言资源中有文字和笑话,请在旁注中告诉译员不要试图翻译它们,而是把它们排除在外,或者用一个更为阴沉的句子代替它们。 否则翻译者可能会逐字地翻译这个笑话,这通常会导致完全的废话。 在我们的案例中,我们有一个翻译和一个笑话作家的最关键的翻译(英语)。
-
试着找一个翻译人员,他的第一语言是他要翻译软件的语言,而不是相反。 否则,他很可能会写出一段可能是正确的文字,但对于母语人士来说,这听起来有些奇怪或过时。 另外,他应该住在你所翻译的国家。 例如瑞士的讲德语的人不会是德语翻译的好select。
-
如果有可能,请让您的公众testing版用户之一了解特定的翻译版本,以validation已翻译的资产和已完成的软件。 我们有一些非常好的和非常糟糕的翻译,取决于提供它的人。 根据我们的一些用户的说法,瑞典语的翻译完全是乱码,但对这件事做任何事都为时过晚。
-
请注意,对于每个带有新function的更新版本,您都必须翻译您的语言资产。 这可能会造成一些严重的开销。
-
请注意,如果您的软件已翻译,最终用户将希望技术支持人员说出自己的语言。 Babelfish再一次很可能不会这样做。
编辑 – 更多点
-
在本地化之间切换尽可能简单。 在Gemsweeper中,我们有一个热键来切换不同的语言。 这使得testing更容易。
-
如果你打算使用奇特的字体,请确保它们包含特殊字符。 我们为Gemsweeperselect的字体对于英文文本来说不错,但是我们不得不手工添加不less字符,只有德文,法文,葡萄牙文,瑞典文……
-
不要编写自己的本地化框架。 像Gettext这样的开源框架可能会更好。 Gettext支持像句子或复数forms的variables这样的特性,并且是坚如磐石的。 本地化的资源被编译,所以没有人可以篡改它们。 另外,您可以使用像Poedit这样的工具翻译文件/检查其他人的翻译,并确保所有string都被正确翻译,并且在更改底层源代码的情况下仍然是最新的。 我已经尝试了滚动我自己和使用Gettext,而我不得不说,Gettext加PoEdit是优越的。
编辑 – 更多点
-
了解不同的文化有不同的数字和date格式。 编号scheme不仅每种文化都有所不同,而且在这种文化中也是有目的的。 在EN-US中,您可以格式化一个数字“-1234”。 '-1,234'或(1,234),这取决于数字的目的是什么。 了解其他文化做同样的事情。
-
知道你从哪里获得你的全球化信息。 例如Windows有CurrentCulture,UICulture和InvariantCulture的设置。 了解每个人的意思,以及它如何与你的系统进行交互(他们不像你想像的那么明显)。
-
如果你打算做东亚翻译,真的做你的功课。 东亚语言与这里的语言有很多不同之处。 除了同时使用多个字母,他们还可以使用不同的布局系统(自上而下)或基于网格。 东亚语言中的数字也可能非常不同。 在美国,你只能在有限的条件下改变系统(比如1和1),除了逗号和句点以外,还有其他的数字因素。
当我们研究“梦幻”和“科南时代”这个国际性的问题时,我们遇到了一些值得记住的问题。 其中一些我们解决了,有些解决了我们,有些我们解决了。 有些我们没有解决…
-
确保你所有的工具和所有的代码都支持你想要使用的所有字符集,并且在项目过程中再次检查这个假设,并且再确认一次。
-
确保使用支持所有要使用的语言的字体。 自称为unicode的大多数字体只是unicode,因为它具有正确的代码点。 这并不意味着它对所有的码点都有可用的字符。
-
文本包装不仅仅是在空格处进行的,因为有些语言不使用空格来分隔单词(中文出现在脑海中)。 确保你的文本包装例程处理文本没有任何空格。
-
正确处理复数在简单的情况下是棘手的,在困难的情况下很难。 确保你对你将要使用的语言有足够的了解,以便能够编写正确处理复数问题的代码。 请记住,英语(和其他“西方”的语言是简单的。
-
不要打断句子,并用它们build立string以适应variables,因为variables可能以不同语言放置在句子的其他地方。 使用占位符。
-
请记住,对于某些语言,占位符的值可能会改变如何编写句子。 语法很难。 确保你有一个处理它的计划。 (具体来说,请确保您有一种方法根据性别,时间等对占位符中使用的值进行分类)。
- 我的菜单和应用程序中的各种列表按字母顺序排列,便于阅读。
清单应该sorting,菜单不应该。 请记住,给定的用户可能希望以多种语言使用您的应用程序,他仍然应该在同一个地方find任何地方。
快捷方式也一样,如果有的话: 不要翻译它们 。
还要记住,国际化和翻译是两回事,分开pipe理。
我想提出以下意见 – 这些是来自一些公司的指导方针,其中一级产品被翻译成31个不同的地区。 遵循这些准则,我们(我们的开发团队而不是整个公司)在翻译方面的生产力最高。
-
不要尝试重复使用错误消息的片段。 例如,不要以为你有两个错误
"You selected the wrong menu item"
和"That menu item is not yet available"
,你可以将"menu item"
提取到一个单独的项目中并在两个地方使用。 所有消息应该是自包含的,因为它们的翻译可以根据上下文而改变。 -
使用一位熟悉技术的专业翻译人员 。 如果你接近BabelFish这样的服务,你将得到你应得的一切。 例如,
"Microsoft Windows"
是全球各地的"Microsoft Windows"
,它不会在德国成为"Microsoft Fenster"
。 -
尽量不要在消息中embeddedvariables(比如
"The %1 has failed"
,其中%1
dynamic变化),因为职位和性别可能会改变:"La table est rubbish"
和"L'Homme est drunk"
。或"The red table"
与"La table rouge"
。 最好使用带有附加参数的通用名词:"The item has failed [%1]"
。 -
只翻译用户期望看到的东西。 在日志文件中logging日志信息(只有你将会使用)应该是英文的(或者你的母语),而不是翻译成类似斯瓦希里语的东西,而你无法阅读。
-
菜单应按functionsorting,而不是sorting。
-
可译文件应该存储在代码的外部 ,并在运行时加载。 这使得翻译成为一个只关注外部文件的问题,而不是试图将更改压入代码中间。 这也使得将来添加其他语言更容易。
这就够了。 最好在你们入睡之前停下来:-)
关于数字的事情:在英文中,据我所知,你只是使用单数1和复数2或更多。 像:“你有1条消息”; “2条消息”; “3 …消息”。 在俄罗斯,这些事情变得更加复杂。 你用1,21,31,41 … 101,121单数(所有以1结束的事物,除非以11结尾)。 然后你用2,3,4的单数所有格 , 22,23,24; 32,33,34 … 102,103,104; 122,123,124.在所有其他情况下,你使用复数所有格的情况 。
这并不是很难实现。 什么是困难的是要实现的东西,将知道如何处理任何先验未知的语言与所有的怪异:-)
这只是数字:-)
到目前为止,我没有太多东西可以添加到很好的答案中,但是这里有几件事要考虑和检查。
- 不要做出假设。 这是所有的规则。 假设区域或语言特定的事物是容易的,并且很难注意到这些假设。
- string比较要非常小心。 有一些语言,如土耳其语,它们的字母与其他字母在视觉上类似,但是不同。
- 使用伪翻译作为烟雾testing。 如果您从资源文件中读取翻译后的string,请创build一个对您来说仍然可以理解的伪翻译版本,但强调应用程序中每个可翻译string的容量和function。 例如,用“CancelXXXX!”之类的字符填充“Cancel”string。 所以它和翻译的string一样宽。 然后您可以testing以确认每个string都将完全显示。 额外的功劳也可能会被渲染到最复杂的angular色,以validation它在所有地方都能正确显示。
- 不要对键盘布局做出假设。 “ASDW”可能是QWERTY键盘方向键的一个很好的控制组,但硬编码使得对其他键盘布局的人使用它(如果不是不可能的话)是不友好的。
- testing各种date设置,然后再次testing。 由于区域设置中“上午/下午”的格式不同,我已经看到了问题。 mm / dd / yyyy与dd / mm / yyyy也出现了很多,但是这里的每一个设置都可能很重要。
- testing各种数字格式,然后再次testing。 例如,您不希望依赖于小数或千位分隔符。
- testing是否有用户login到服务器。 这可能是更具体的Windows,但它很容易得到configuration的服务器上的组件,以便它使用用户login时login的用户的区域设置和用户未login时的默认区域设置。会造成奇怪的,间歇性的行为。
- testing各种区域和语言设置。 例如,Windows不仅具有区域和语言设置,而且IE具有自己的语言设置。 例如,首先列出的en-us的IE客户端的行为可能并不总是与en-nz列出的行为相同。
- 确保您的翻译员了解业务和语言,然后与其他人交叉核对。 任何时候使用应用程序特定的术语时要非常小心。 如果您的程序在应用程序中使用了特定的词语,那么请确保它们在每个实例中都以相似的方式进行翻译,包括在帮助文本中。 如果你有特定的语言目标,你甚至可以提前翻译这些单词,并确保它们不会在目标语言中翻译得不好。 这更多的是一个产品研究的东西,但它可以在界面中使用什么词语上有所不同,如果这些词汇是从一开始就有的话,那么每个人都会更容易。 你也希望避免可能翻译不好的成语。
好的,我想说的比我想的要多…
有一件事情我已经学会了很难:如果你有几个需要翻译的文件,在名字中包含一个额外的标签,这样以后你可以在整个文件夹中search该标签。
例如,不是命名文件'sample-database.txt',而是命名英文版本'sample-database-loc-en.txt',意大利语版本'sample-database-loc-it.txt
我在StackOverflow的第一个答案,所以如果有些愚蠢说,请原谅。
从我的经验:
- PHP :gettext非常有帮助;
- 非西方语言 :到处都是UTF-8(代码,DB),到目前为止我们做得很好;
- 你在实践中遇到过什么具体的问题吗? 将i18n中的长段落分成不同的句子可以降低翻译成本,如果string在网站中重复多次,只需要翻译一次即可。 但是,要小心,如果你把文本分割得太多,译员就会失去语境;
- 我看到很多项目和网站让他们的社区为他们的应用程序和内容提供翻译。 你是否推荐这个,有什么好的策略来确保你有一个好的翻译? 如果你有很多的志愿者去参加,但是根据你有多less文字,你可能真的需要大量的志愿者。 总是要确保你有一个你信任的人是一个语言项目的领导者,作为控制翻译准确性的certificate读者。
- 整理/sorting规则在各种语言之间可能会有很大差异:ä德语sorting与瑞典语sorting不同。 所以sorting需要针对文化。
- 上/下套装可以容纳惊喜:德国的“尖锐的S”字符ß没有大写版本,并且被转换为“SS”,或者如果正确性很重要,则保持小写。 土耳其语有一个无点小写我和一个大写点缀我。
- 对于多语言networking应用程序,请仔细考虑如何决定要显示的版本以及如何将其应用到url中。 用户应该始终能够手动select语言,并且您希望search引擎在不同的URL下find不同的语言版本。
- 一些东亚语言(即日语和中文,也许是其他语言)在词语之间没有空格
- 日语(也可能是其他人)具有阿拉伯数字和空格的单独版本(“全宽”),甚至有一些自己的字符(半angular和全angular片假名)的两个版本。
是的,这是一个很大的问题。 正确的做法是非常多的工作。
在我的程序中,我为每一段文本使用一个整数键,并根据需要根据语言在文件中查找它。 代码中没有任何string,只有键。 我用C ++中的“enum”来定义它们,所以我实际上并没有input数字。 我写了一个实用程序来同步各种语言文件,当我添加更多的枚举和翻译填补空白。
每个键还有一个关联的工具提示,图像,键盘快捷键等
至于时间和date…再次,这比你想象的要复杂得多,但不是PHP为你处理? (我不知道,我是一个C ++的人…)
PHP在内部将string表示为字节stream,对于编码很重要的情况,采用iso-8859-1。 大多数情况下,你可以在所有地方使用UTF-8,你会没事的。 一个问题是,如果你的网站从用户那里得到了input,那么你绝对不能100%确定他们正在以正确的编码提交内容。 您可能需要使用mb_detect_encoding
validationinput,或者使用带有“异国情调”字符的隐藏字段进行validation。
请注意,PHP中所有与string相关的函数都是以字符为基础的,假定字符=字节。 这意味着你通常不能相信string函数。 看看这个页面的更多细节。
另一个好的PHP资源是Nick Nettleton的cheatsheet 。
与字符集/编码密切相关的主题是整理 。 你需要你的归类来匹配你正在使用的语言/文化。 至less在MySql中(可能在其他RDBMS中也是如此),可以在不同级别上指定sorting规则,比如每个数据库,每个表,每个列甚至是查询本身。