最佳实践 javascript 和多语言

什么是多语言网站使用 DOM 的最佳实践与 javascript 操作?我使用 javascript 构建了网站的一些动态部分。我的第一个想法是使用一个以文本字符串和语言代码为索引的数组。这是个好主意吗?

105182 次浏览

当我以前构建过多语言站点(不是很大的站点,所以这个站点可能扩展得不太好)时,我会保留一系列“语言”文件:

  • Lang.en.js
  • Lang.it.js
  • Lang Fr.js

每个文件都声明了一个对象,这个对象基本上就是一个从关键字到语言短语的映射:

// lang.en.js
lang = {
greeting : "Hello"
};


// lang.fr.js
lang = {
greeting : "Bonjour"
};

动态加载其中一个文件,然后你需要做的就是引用地图上的密钥:

document.onload = function() {
alert(lang.greeting);
};

当然,还有很多其他的方法可以做到这一点,也有很多方法可以更好地做到这一点: 把它封装成一个函数,这样你的“字典”中缺少的一个短语就可以得到优雅的处理,或者甚至可以用 OOP 来完成整个操作,让它管理包含文件的动态,它甚至可以为你绘制语言选择器,等等。

var l = new Language('en');
l.get('greeting');

刚刚在 javascript 中找到一篇关于 i18n 的文章:
Http://24ways.org/2007/javascript-internationalisation

尽管使用 i18n + javascript 进行简单的谷歌搜索可以找到很多替代方案。

最后,这取决于你希望它是怎样的 很深。对于几种语言来说,一个文件就足够了。

您可以使用像 Jquery这样的框架,使用 span 来标识文本(使用类) ,然后使用每个 span 的 id 来查找所选语言中的相应文本。
1行 Jquery,完成。

在设计多语言支持时,有几件事你需要记住:

1-将代码与数据分开(例如,不要将字符串硬编码到函数中)

创建一个格式化钩子函数来处理本地化差异。允许可格式化字符串(“{0}”)优于连接(“欢迎来到”+ value) ,原因有很多:

  • 在某些语言中,数字的格式是1.234.678,00,而不是1.234,567.00
  • 复数形式通常不像在单数结尾附加一个“ s”那么简单
  • 语法规则是不同的,可以影响事物的顺序,所以你应该允许动态数据被附加在翻译钩子之后: 例如,“欢迎来到{0}”变成日语中的 “{0}他优酷索”(提醒你,这在几乎每种语言中都会发生)。

3-确保你可以格式化字符串 之后的翻译钩运行,所以你可以重用键。

4-在任何情况下,都不要将钩子数据库输出到翻译工具.如果有多语言数据,请在数据库中创建单独的表/行。我见过很多人在这个问题上不费吹灰之力就犯了错误(通常是在国家和州/省的表格中)。

5-为创建键创建显式的编码实践规则。格式化程序实用程序函数(看起来类似于 翻译(“ hello world”))将使用键作为参数,而具有轻微变化的键会使维护变得非常烦人。例如,在下面的示例中,您可能会得到三个键: “ enter you name”、“ enter your name:”、“ enter your name:”。选择一种格式(例如没有冒号,修剪)并捕捉代码检查中的差异。不要以编程方式执行此过滤,因为它可能会触发误报。

注意,在翻译表中可能需要 HTML 标记(例如,如果您需要在句子中加粗一个单词,或者需要脚注医学参考)。广泛测试一下。

有几种导入语言字符串的方法。理想情况下,您应该有一个 language. lang.js 文件的多个版本,使用服务器端代码在它们之间切换,并从 HTML 文件的底部引用该文件。通过 AJAX 提取文件也是一种选择,但是可能会引起延迟。将 language. js 合并到主代码文件中是不可取的,因为您将失去文件缓存的好处。

8-使用目标语言进行测试。这听起来很傻,但我曾经看到过一个严重的错误,因为程序员没有检查键中是否存在“ é”。

您应该了解在经典 JS 组件中已经完成了哪些工作-使用 Dojo、 Ext、 FCKEditor、 TinyMCE 等。你会发现很多好主意。

通常,它最终是您在标记上设置的某种属性,然后根据属性的值,将标记的内容替换为在翻译文件中找到的翻译。

需要记住的一件事是语言集的演化(当代码演化时,是否需要重新翻译整个集合)。我们将翻译保存在 PO 文件(Gnu Gettext)中,并且有一个脚本可以将 PO 文件转换为可以使用 JS 文件的文件。

此外:

  • 总是使用 UTF-8-这听起来很傻,但是如果你从一开始就不使用 UTF-8(HTML head + JS 编码) ,你很快就会崩溃。
  • 使用英文字符串作为你翻译的关键-这样你就不会最终得到像: lang 这样的东西。问候 = ‘ Hello world’-but lang [‘ Hello world’] = ‘ Hello world’;
function Language(lang)
{
var __construct = function() {
if (eval('typeof ' + lang) == 'undefined')
{
lang = "en";
}
return;
}()


this.getStr = function(str, defaultStr) {
var retStr = eval('eval(lang).' + str);
if (typeof retStr != 'undefined')
{
return retStr;
} else {
if (typeof defaultStr != 'undefined')
{
return defaultStr;
} else {
return eval('en.' + str);
}
}
}
}

添加到页面之后,您可以这样处理它:

var en = {
SelPlace:"Select this place?",
Save:"Saved."
};


var tr = {
SelPlace:"Burayı seçmek istiyor musunuz?"
};


var translator = new Language("en");
alert(translator.getStr("SelPlace")); // result: Select this place?
alert(translator.getStr("Save")); // result: Saved.
alert(translator.getStr("DFKASFASDFJK", "Default string for non-existent string")); // result: Default string for non-existent string


var translator = new Language("tr");
alert(translator.getStr("SelPlace")); // result: Burayı seçmek istiyor musunuz?
alert(translator.getStr("Save")); // result: Saved. (because it doesn't exist in this language, borrowed from english as default)
alert(translator.getStr("DFKASFASDFJK", "Default string for non-existent string")); // result: Default string for non-existent string

如果使用未定义的语言调用该类,则将选择 English ()。

在阅读了 nickf 和 Leo 的精彩答案之后,我创建了以下 CommonJS 样式的 language. js 来管理我的所有字符串(还可以选择使用 胡子来格式化它们) :

var Mustache = require('mustache');


var LANGUAGE = {
general: {
welcome: "Welcome \{\{name}}!"
}
};


function _get_string(key) {
var parts = key.split('.');
var result = LANGUAGE, i;
for (i = 0; i < parts.length; ++i) {
result = result[parts[i]];
}
return result;
}


module.exports = function(key, params) {
var str = _get_string(key);
if (!params || _.isEmpty(params)) {
return str;
}
return Mustache.render(str, params);
};

我就是这样得到一个字符串的:

var L = require('language');
var the_string = L('general.welcome', {name='Joe'});

对于 Spring bundle 和 JavaScript,有一个简单的解决方案: 在模板中生成 i18n 数组(例如 JSP) ,然后在 JavaScript 中使用它:

JSP:

<html>
<script type="text/javascript">
var i18n = [];
<c:forEach var='key' items='<%=new String[]{"common.deleted","common.saved","common.enabled","common.disabled","...}%>'>
i18n['${key}'] = '<spring:message code="${key}"/>';
</c:forEach>
</script>
</html>

在 JS 中:

alert(i18n["common.deleted"]);

参见 解析 spring: 用于 i18n 国际化的 javascript 中的消息

这样你就可以用一个 js 代码来表示多种语言的多个单词:

var strings = new Object();


if(navigator.browserLanguage){
lang = navigator.browserLanguage;
}else{
lang = navigator.language;
}


lang = lang.substr(0,2).toLowerCase();






if(lang=='fa'){/////////////////////////////Persian////////////////////////////////////////////////////




strings["Contents"]                              = "فهرست";
strings["Index"]                                 = "شاخص";
strings["Search"]                                = "جستجو";
strings["Bookmark"]                              = "ذخیره";


strings["Loading the data for search..."]        = "در حال جسنجوی متن...";
strings["Type in the word(s) to search for:"]    = "لغت مد نظر خود را اینجا تایپ کنید:";
strings["Search title only"]                     = "جستجو بر اساس عنوان";
strings["Search previous results"]               = "جستجو در نتایج قبلی";
strings["Display"]                               = "نمایش";
strings["No topics found!"]                      = "موردی یافت نشد!";


strings["Type in the keyword to find:"]          = "کلیدواژه برای یافتن تایپ کنید";


strings["Show all"]                              = "نمایش همه";
strings["Hide all"]                              = "پنهان کردن";
strings["Previous"]                              = "قبلی";
strings["Next"]                                  = "بعدی";


strings["Loading table of contents..."]          = "در حال بارگزاری جدول فهرست...";


strings["Topics:"]                               = "عنوان ها";
strings["Current topic:"]                        = "عنوان جاری:";
strings["Remove"]                                = "پاک کردن";
strings["Add"]                                   = "افزودن";


}else{//////////////////////////////////////English///////////////////////////////////////////////////


strings["Contents"]                              = "Contents";
strings["Index"]                                 = "Index";
strings["Search"]                                = "Search";
strings["Bookmark"]                              = "Bookmark";


strings["Loading the data for search..."]        = "Loading the data for search...";
strings["Type in the word(s) to search for:"]    = "Type in the word(s) to search for:";
strings["Search title only"]                     = "Search title only";
strings["Search previous results"]               = "Search previous results";
strings["Display"]                               = "Display";
strings["No topics found!"]                      = "No topics found!";


strings["Type in the keyword to find:"]          = "Type in the keyword to find:";


strings["Show all"]                              = "Show all";
strings["Hide all"]                              = "Hide all";
strings["Previous"]                              = "Previous";
strings["Next"]                                  = "Next";


strings["Loading table of contents..."]          = "Loading table of contents...";


strings["Topics:"]                               = "Topics:";
strings["Current topic:"]                        = "Current topic:";
strings["Remove"]                                = "Remove";
strings["Add"]                                   = "Add";


}

您可以在此代码中添加另一个 lang 并在 html 代码中设置对象。 我用波斯语为波斯语和英语,你可以使用任何类型的语言只是创建这部分代码的如果-Else 语句的副本。

你可以使用谷歌翻译:

<div id="google_translate_element" style = "float: left; margin-left: 10px;"></div>


<script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({pageLanguage: 'en', layout: google.translate.TranslateElement.InlineLayout.HORIZONTAL}, 'google_translate_element');
}
</script>


<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>


</div><input type = "text" style = "display: inline; margin-left: 8%;" class = "sear" placeholder = "Search people..."><button class = "bar">&#128270;</button>

class Language {
constructor(lang) {
var __construct = function (){
if (eval('typeof ' + lang) == 'undefined'){
lang = "en";
}
return;
};
this.getStr = function (str){
var retStr = eval('eval(lang).' + str);
if (typeof retStr != 'undefined'){
return retStr;
} else {
return str;
}
};
}
}


var en = {
Save:"Saved."
};


var fa = {
Save:"ذخیره"
};


var translator = new Language("fa");
console.log(translator.getStr("Save"));