Javascript 字符串和标签本地化和全球化的最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14358817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best practice for localization and globalization of strings and labels
提问by
I'm a member of a team with more than 20 developers. Each developer works on a separate module (something near 10 modules). In each module we might have at least 50 CRUD forms, which means that we currently have near 500 add buttons, save buttons, edit buttons, etc.
我是一个拥有 20 多名开发人员的团队的成员。每个开发人员都在一个单独的模块上工作(大约有 10 个模块)。在每个模块中,我们可能至少有 50 个 CRUD 表单,这意味着我们目前有近 500 个添加按钮、保存按钮、编辑按钮等。
However, because we want to globalized our application, we need to be able to translate texts in our application. For example, everywhere, the word addshould become ajouterfor French users.
然而,因为我们想要全球化我们的应用程序,我们需要能够翻译我们应用程序中的文本。例如,在任何地方,对于法语用户来说,add这个词都应该成为ajouter。
What we've done till now, is that for each view in UI or Presentation Layer, we have a dictionary of key/value pairs of translations. Then while rendering the view, we translate required texts and strings using this dictionary. However, this approach, we've come to have something near 500 addin 500 dictionaries. This means that we've breached DRY principal.
到目前为止,我们所做的是,对于 UI 或表示层中的每个视图,我们都有一个键/值对翻译字典。然后在渲染视图时,我们使用这个字典翻译所需的文本和字符串。但是,通过这种方法,我们已经在 500 个词典中添加了近 500个。这意味着我们违反了 DRY 原则。
On the other hand, if we centralize common strings, like putting addin one place, and ask developers to use it everywhere, we encounter the problem of not being sure if a string is already defined in the centralized dictionary or not.
另一方面,如果我们把常用的字符串集中起来,比如把add放在一个地方,并要求开发者到处使用,就会遇到不确定集中字典中是否已经定义了一个字符串的问题。
One other options might be to have no translation dictionary and use online translation services like Google Translate, Bing Translator, etc.
另一种选择可能是没有翻译词典并使用在线翻译服务,如谷歌翻译、必应翻译等。
Another problem that we've encountered is that some developers under the stress of delivering the project on-time can't remember the translation keys. For example, for the text of the add button, a developer has used addwhile another developer has used new, etc.
我们遇到的另一个问题是一些开发人员在按时交付项目的压力下无法记住翻译键。例如,对于添加按钮的文本,一个开发者使用了add而另一个开发者使用了new等。
What is the best practice, or most well-known method for globalization and localization of string resources of an application?
应用程序字符串资源全球化和本地化的最佳实践或最著名的方法是什么?
采纳答案by Afshin Mehrabani
As far as I know, there's a good library called localeplanetfor Localization and Internationalization in JavaScript. Furthermore, I think it's native and has no dependencies to other libraries (e.g. jQuery)
据我所知,有一个很好的库localeplanet在 JavaScript 中调用本地化和国际化。此外,我认为它是原生的,对其他库(例如 jQuery)没有依赖关系
Here's the website of library: http://www.localeplanet.com/
这是图书馆的网站:http: //www.localeplanet.com/
Also look at this article by Mozilla, you can find very good method and algorithms for client-side translation: http://blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with-a-little-help-from-json-and-the-server/
也看看 Mozilla 的这篇文章,你可以找到非常好的客户端翻译方法和算法:http: //blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with- a-little-help-from-json-and-the-server/
The common part of all those articles/libraries is that they use a i18nclass and a getmethod (in some ways also defining an smaller function name like _) for retrieving/converting the keyto the value. In my explaining the keymeans that string you want to translate and the valuemeans translated string.
Then, you just need a JSON document to store key's and value's.
所有这些文章/库的共同部分是它们使用一个i18n类和一个get方法(在某些方面还定义了一个较小的函数名称,如_)来检索/转换key为value. 在我解释key要value翻译的字符串的意思和翻译字符串的意思时。
然后,您只需要一个 JSON 文档来存储key's 和value's。
For example:
例如:
var _ = document.webL10n.get;
alert(_('test'));
And here the JSON:
这里是 JSON:
{ test: "blah blah" }
I believe using current popular libraries solutions is a good approach.
我相信使用当前流行的库解决方案是一个很好的方法。
回答by Omid Shariati
When you're faced with a problem to solve (and frankly, who isn't these days?), the basic strategy usually taken by we computer people is called “divide and conquer.” It goes like this:
- Conceptualize the specific problem as a set of smaller sub-problems.
- Solve each smaller problem.
- Combine the results into a solution of the specific problem.
But “divide and conquer” is not the only possible strategy. We can also take a more generalist approach:
- Conceptualize the specific problem as a special case of a more general problem.
- Somehow solve the general problem.
- Adapt the solution of the general problem to the specific problem.
- Eric Lippert
当您面临要解决的问题时(坦率地说,现在谁不是?),我们计算机人员通常采取的基本策略称为“分而治之”。它是这样的:
- 将特定问题概念化为一组较小的子问题。
- 解决每个较小的问题。
- 将结果组合成特定问题的解决方案。
但“分而治之”并不是唯一可能的策略。我们还可以采用更通用的方法:
- 将特定问题概念化为更一般问题的特例。
- 以某种方式解决一般问题。
- 使一般问题的解决方案适应具体问题。
- 埃里克·利珀特
I believe many solutions already exist for this problem in server-side languages such as ASP.Net/C#.
我相信在服务器端语言(例如 ASP.Net/C#)中已经存在针对此问题的许多解决方案。
I've outlined some of the major aspects of the problem
我已经概述了问题的一些主要方面
Issue: We need to load data only for the desired language
Solution: For this purpose we save data to a separate files for each language
问题:我们只需要加载所需语言的数据
解决方案:为此,我们将每种语言的数据保存到单独的文件中
ex. res.de.js, res.fr.js, res.en.js, res.js(for default language)
前任。res.de.js, res.fr.js, res.en.js, res.js(默认语言)
Issue: Resource files for each page should be separated so we only get the data we need
Solution: We can use some tools that already exist like https://github.com/rgrove/lazyload
Issue: We need a key/value pair structure to save our data
Solution: I suggest a javascript object instead of string/string air. We can benefit from the intellisense from an IDE
Issue: General members should be stored in a public file and all pages should access them
Solution: For this purpose I make a folder in the root of web application called Global_Resources and a folder to store global file for each sub folders we named it 'Local_Resources'
Issue: Each subsystems/subfolders/modules member should override the Global_Resources members on their scope
Solution: I considered a file for each
问题:每个页面的资源文件应该分开,这样我们只能得到我们需要的数据
解决方案:我们可以使用一些已经存在的工具,比如 https://github.com/rgrove/lazyload
问题:我们需要一个键/值对结构来保存我们的数据
解决方案:我建议使用 javascript 对象而不是字符串/字符串空气。我们可以从 IDE 的智能感知中受益
问题:一般成员应存储在公共文件中,所有页面都应访问它们
解决方案:为此,我在 Web 应用程序的根目录中创建了一个名为 Global_Resources 的文件夹和一个文件夹来存储我们命名为“Local_Resources”的每个子文件夹的全局文件
问题:每个子系统/子文件夹/模块成员应覆盖其作用域内的 Global_Resources 成员
解决方案:我考虑了每个文件
Application Structure
应用结构
root/ Global_Resources/ default.js default.fr.js UserManagementSystem/ Local_Resources/ default.js default.fr.js createUser.js Login.htm CreateUser.htm
root/ Global_Resources/ default.js default.fr.js UserManagementSystem/ Local_Resources/ default.js default.fr.js createUser.js Login.htm CreateUser.htm
The corresponding code for the files:
文件对应的代码:
Global_Resources/default.js
Global_Resources/default.js
var res = {
Create : "Create",
Update : "Save Changes",
Delete : "Delete"
};
Global_Resources/default.fr.js
Global_Resources/default.fr.js
var res = {
Create : "créer",
Update : "Enregistrer les modifications",
Delete : "effacer"
};
The resource file for the desired language should be loaded on the page selected from Global_Resource - This should be the first file that is loaded on all the pages.
所需语言的资源文件应该加载到从 Global_Resource 中选择的页面上 - 这应该是所有页面上加载的第一个文件。
UserManagementSystem/Local_Resources/default.js
用户管理系统/Local_Resources/default.js
res.Name = "Name";
res.UserName = "UserName";
res.Password = "Password";
UserManagementSystem/Local_Resources/default.fr.js
用户管理系统/Local_Resources/default.fr.js
res.Name = "nom";
res.UserName = "Nom d'utilisateur";
res.Password = "Mot de passe";
UserManagementSystem/Local_Resources/createUser.js
用户管理系统/Local_Resources/createUser.js
// Override res.Create on Global_Resources/default.js
res.Create = "Create User";
UserManagementSystem/Local_Resources/createUser.fr.js
用户管理系统/Local_Resources/createUser.fr.js
// Override Global_Resources/default.fr.js
res.Create = "Créer un utilisateur";
manager.js file(this file should be load last)
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");
Hope it helps :)
希望能帮助到你 :)
回答by BalaKrishnan?
jQuery.i18nis a lightweight jQuery plugin for enabling internationalization in your web pages. It allows you to package custom resource strings in ‘.properties' files, just like in Java Resource Bundles. It loads and parses resource bundles (.properties) based on provided language or language reported by browser.
jQuery.i18n是一个轻量级的 jQuery 插件,用于在您的网页中启用国际化。它允许您将自定义资源字符串打包到“.properties”文件中,就像在 Java 资源包中一样。它根据提供的语言或浏览器报告的语言加载和解析资源包 (.properties)。
to know more about this take a look at the How to internationalize your pages using JQuery?
要了解更多信息,请查看如何使用 JQuery 国际化您的页面?

