字符串和标签的本地化和全球化的最佳实践

111 javascript globalization translation localization client-side

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

但是,因为我们想要使我们的应用程序全球化,所以我们需要能够在我们的应用程序中翻译文本.例如,无处不在,单词add应该成为法国用户的焦点.

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

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

另一个选择可能是没有翻译词典并使用谷歌翻译,Bing翻译等在线翻译服务.

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

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

Afs*_*ani 50

据我所知,有一个很好的库localeplanet,需要在JavaScript中进行本地化和国际化.此外,我认为它是原生的,并且与其他库没有依赖关系(例如jQuery)

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

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

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

例如:

var _ = document.webL10n.get;
alert(_('test'));
Run Code Online (Sandbox Code Playgroud)

这里是JSON:

{ test: "blah blah" }
Run Code Online (Sandbox Code Playgroud)

我相信使用当前流行的库解决方案是一种很好的方法.

  • 无意冒犯,但这不是 Afshin 已经尝试过的吗?他的问题是不同的开发人员很难记住要使用哪些键。我同意你所描述的方法是要走的路。我不明白它会如何。顺便说一句,感谢伟大的链接。 (2认同)

Omi*_*ati 45

当你面临一个需要解决的问题时(坦率地说,现在不是这些人?),我们计算机人员通常采取的基本策略叫做"分而治之".它是这样的:

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

但"分而治之"并不是唯一可行的策略.我们也可以采取更通俗的方法:

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

- Eric Lippert

我相信在服务器端语言(如ASP.Net/C#)中已存在许多解决此问题的解决方案.

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

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

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

恩.res.de.js,res.fr.js,res.en.js,res.js(默认语言)

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

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

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

    解决方案:我建议使用javascript对象而不是string/string air.我们可以从IDE的intellisense中受益

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

    解决方案:为此,我在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
Run Code Online (Sandbox Code Playgroud)

文件的相应代码:

Global_Resources/default.js

var res = {
    Create : "Create",
    Update : "Save Changes",
    Delete : "Delete"
};
Run Code Online (Sandbox Code Playgroud)

Global_Resources/default.fr.js

var res = {
    Create : "créer",
    Update : "Enregistrer les modifications",
    Delete : "effacer"
};
Run Code Online (Sandbox Code Playgroud)

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

UserManagementSystem/Local_Resources/default.js

res.Name = "Name";
res.UserName = "UserName";
res.Password = "Password";
Run Code Online (Sandbox Code Playgroud)

UserManagementSystem/Local_Resources/default.fr.js

res.Name = "nom";
res.UserName = "Nom d'utilisateur";
res.Password = "Mot de passe";
Run Code Online (Sandbox Code Playgroud)

UserManagementSystem/Local_Resources/createUser.js

// Override res.Create on Global_Resources/default.js
res.Create = "Create User"; 
Run Code Online (Sandbox Code Playgroud)

UserManagementSystem/Local_Resources/createUser.fr.js

// Override Global_Resources/default.fr.js
res.Create = "Créer un utilisateur";
Run Code Online (Sandbox Code Playgroud)

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");
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你 :)

  • 我不喜欢这种方法的唯一方法是本地化和开发是紧密耦合的...所以当添加英语(无论是什么默认值)字符串时,其余的语言必须通过代码更新.我宁愿使用某种类型的翻译文件中的工具创建JSON.还是一个很好的代表! (7认同)

Bal*_*an웃 13

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

要了解更多相关内容,请参阅如何使用JQuery将页面国际化?