128

我是一个拥有 20 多名开发人员的团队的成员。每个开发人员都在一个单独的模块上工作(大约 10 个模块)。在每个模块中,我们可能至少有 50 个 CRUD 表单,这意味着我们目前有近 500 个添加按钮保存按钮编辑按钮等。

然而,因为我们想要全球化我们的应用程序,我们需要能够在我们的应用程序中翻译文本。例如,在任何地方,对于法语用户来说, add这个词都应该变成ajouter 。

到目前为止,我们所做的是,对于 UI 或表示层中的每个视图,我们都有一个翻译键/值对的字典。然后在渲染视图时,我们使用这个字典翻译所需的文本和字符串。但是,通过这种方法,我们已经在 500 个字典中添加了近 500 个内容。这意味着我们违反了 DRY 原则。

另一方面,如果我们将常用字符串集中起来,比如将add放在一个地方,并要求开发人员在任何地方使用它,我们就会遇到不确定字符串是否已经在集中字典中定义的问题。

另一种选择可能是没有翻译词典并使用在线翻译服务,如谷歌翻译、必应翻译等。

我们遇到的另一个问题是一些开发人员在按时交付项目的压力下无法记住翻译键。例如,对于添加按钮的文本,一个开发人员使用了add而另一个开发人员使用了new等。

应用程序的字符串资源全球化和本地化的最佳实践或最著名的方法是什么?

4

3 回答 3

53

据我所知,有一个很好的库,叫做localeplanetJavaScript 中的本地化和国际化。此外,我认为它是原生的,并且不依赖于其他库(例如 jQuery)

这是图书馆的网站:http ://www.localeplanet.com/

另外看看Mozilla的这篇文章,你可以找到非常好的客户端翻译方法和算法:http: //blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with-来自 json 和服务器的小帮助/

所有这些文章/库的共同部分是它们使用一个i18n类和一个get方法(在某些方面还定义了一个较小的函数名称,如_)来检索/key转换value. 在我解释key要翻译的字符串的value意思和翻译的字符串的意思时。
然后,您只需要一个 JSON 文档来存储key's 和value's。

例如:

var _ = document.webL10n.get;
alert(_('test'));

这里是 JSON:

{ test: "blah blah" }

我相信使用当前流行的图书馆解决方案是一个好方法。

于 2013-01-16T13:03:42.613 回答
47

当您面临要解决的问题时(坦率地说,现在谁不是?),我们计算机人通常采取的基本策略称为“分而治之”。它是这样的:

  • 将特定问题概念化为一组较小的子问题。
  • 解决每个较小的问题。
  • 将结果组合成特定问题的解决方案。

但“分而治之”并不是唯一可能的策略。我们还可以采取更通用的方法:

  • 将特定问题概念化为更一般问题的特例。
  • 以某种方式解决一般问题。
  • 使一般问题的解决方案适应具体问题。

- 埃里克·利珀特

我相信在 ASP.Net/C# 等服务器端语言中已经存在许多解决方案来解决这个问题。

我已经概述了问题的一些主要方面

  • 问题:我们只需要加载所需语言的数据

    解决方案:为此,我们将数据保存到每种语言的单独文件中

前任。res.de.js, res.fr.js, res.en.js, res.js(默认语言)

  • 问题:每个页面的资源文件应该分开,所以我们只得到我们需要的数据

    解决方案:我们可以使用一些已经存在的工具,例如 https://github.com/rgrove/lazyload

  • 问题:我们需要一个键/值对结构来保存我们的数据

    解决方案:我建议使用 javascript 对象而不是字符串/字符串空气。我们可以从 IDE 的智能感知中受益

  • 问题:一般成员应存储在公共文件中,所有页面都应访问它们

    解决方案:为此,我在 Web 应用程序的根目录中创建了一个名为 Global_Resources 的文件夹,并为每个子文件夹存储全局文件,我们将其命名为“Local_Resources”

  • 问题:每个子系统/子文件夹/模块成员都应覆盖其范围内的 Global_Resources 成员

    解决方案:我考虑了每个文件

应用结构

root/
    Global_Resources/
        default.js
        default.fr.js
    UserManagementSystem/
        Local_Resources/
            default.js
            default.fr.js
            createUser.js
        Login.htm
        CreateUser.htm

文件对应的代码:

Global_Resources/default.js

var res = {
    Create : "Create",
    Update : "Save Changes",
    Delete : "Delete"
};

Global_Resources/default.fr.js

var res = {
    Create : "créer",
    Update : "Enregistrer les modifications",
    Delete : "effacer"
};

所需语言的资源文件应加载到从 Global_Resource 选择的页面上 - 这应该是所有页面上加载的第一个文件。

用户管理系统/Local_Resources/default.js

res.Name = "Name";
res.UserName = "UserName";
res.Password = "Password";

UserManagementSystem/Local_Resources/default.fr.js

res.Name = "nom";
res.UserName = "Nom d'utilisateur";
res.Password = "Mot de passe";

UserManagementSystem/Local_Resources/createUser.js

// Override res.Create on Global_Resources/default.js
res.Create = "Create User"; 

UserManagementSystem/Local_Resources/createUser.fr.js

// Override Global_Resources/default.fr.js
res.Create = "Créer un utilisateur";

manager.js 文件(这个文件应该最后加载)

res.lang = "fr";

var globalResourcePath = "Global_Resources";
var resourceFiles = [];

var currentFile = globalResourcePath + "\\default" + res.lang + ".js" ;

if(!IsFileExist(currentFile))
    currentFile = globalResourcePath + "\\default.js" ;
if(!IsFileExist(currentFile)) throw new Exception("File Not Found");

resourceFiles.push(currentFile);

// Push parent folder on folder into folder
foreach(var folder in parent folder of current page)
{
    currentFile = folder + "\\Local_Resource\\default." + res.lang + ".js";

    if(!IsExist(currentFile))
        currentFile = folder + "\\Local_Resource\\default.js";
    if(!IsExist(currentFile)) throw new Exception("File Not Found");

    resourceFiles.push(currentFile);
}

for(int i = 0; i < resourceFiles.length; i++) { Load.js(resourceFiles[i]); }

// Get current page name
var pageNameWithoutExtension = "SomePage";

currentFile = currentPageFolderPath + pageNameWithoutExtension + res.lang + ".js" ;

if(!IsExist(currentFile))
    currentFile = currentPageFolderPath + pageNameWithoutExtension + ".js" ;
if(!IsExist(currentFile)) throw new Exception("File Not Found");

希望能帮助到你 :)

于 2013-01-28T05:56:56.557 回答
14

jQuery.i18n是一个轻量级的 jQuery 插件,用于在您的网页中实现国际化。它允许您将自定义资源字符串打包到“.properties”文件中,就像在 Java 资源包中一样。它根据提供的语言或浏览器报告的语言加载和解析资源包(.properties)。

要了解更多信息,请查看如何使用 JQuery 国际化您的页面?

于 2013-01-16T12:52:09.263 回答