有时候,我们需要设计和制作全球化的站点,这些站点有一个特点,那就是要适应许多地区和文化,其中包括,站点中的一些内容要根据实际使用情况进行本地化。许多情况下,后端会输出本地化之后的内容,甚至有时候,不同地区和语言的网站都是不同的。然而,如果在某一场景内,需要通过 Web 前端来进行已知内容的本地化控制,例如一些文本的设置,这时便需要通过 Web 前端本地化技术来实现。熟悉 C# 开发的工程师可能都非常了解资源文件在本地化方面起到的作用;然而,当进入 JavaScript 的世界后,似乎至少当前版本本身并没有内置支持这类自动化的本地化功能,因此,需要通过一些方式,来实现这一切。为此,我们需要设计一套通用方案,来提供这类服务,同时支持以下这些功能。
- 模块化,做到各资源组互不干扰。
- 能够设置默认语言。
- 可以注册语言包。
- 可以获取指定本地化文本。
- 可以设置或获取某一特定语言的文本。
- 符合 ISO 639 规范。
为此,我们需要通过一个类来实现,这个类会被用于任何需要用到资源组的地方,不同模块可以初始化不同的实例,从而做到相互隔离。为了统一,以下均用 ECMA Script 5 来描述。
var Local = function () {
this.defaultLang = null; // 默认语言。
this._strings = {}; // 语言包。
};
Local.prototype.regStrings = function (lang, value) {
// ToDo: Implement it. 注册语言包。
};
Local.prototype.getString = function (key, lang) {
// ToDo: Implement it. 获取某一本地文本。
};
Local.prototype.specificString = function (lang, key, value) {
// ToDo: Implement it. 获取或设置某一特定语言的某一文本。
};
不过在此上面的这些 To-Do 之前,我们还需要先行搞定一件事情:获取当前的语言。当前的语言指的是相对于当前页面的一个全局变量,用于标识当前使用哪个语言,我们需要用到一个变量来存储当前的语言,然后使用一个方法将其暴露出来,这个方法也提供设置功能。为了防止这个变量的引用暴露,我们在外面用一个匿名函数将其包起来,然后立即执行。
(function () {
var _lang;
Local.lang = function (value) {
if (arguments.length > 0 && !!value) {
_lang = value.toString().toLowerCase();
}
return _lang;
}
})();
然而,这样太不够自动化了。至少,我们还是有办法获取到当前用户的语言使用情况的。
_lang = navigator.language
|| navigator.userLanguage
|| navigator.browserLanguage
|| navigator.systemLanguage;
但是这段代码加在哪里最合适呢?事实上,我们可以对 Local.lang 函数进行改写,使其支持自动和手动两种模式。
- 如果传入参数为字符串,那么此即语言代号,记录之。
- 如果传入的参数为 true,则启用自动模式来设置值,设置值的方式如前面所述。如果实在获取不到,那么使用预设的一个默认值。
- 如果传入的参数为 false,那么意味着取消之前的设置,切换回默认值。
- 当没有传入参数,或传入参数为空时,返回当前值。如果当前没有值,采用自动模式自行先设置一个值,然后再取出来。
于是,该函数即被调整如下,同时多加入了一个属性,即默认语言。
Local.defaultLang = "en";
/**
* 获取或设置当前的语言标识符,使用 ISO 639 里的代码表示。
* @param value 可选。设置值。
*/
Local.lang = function (value) {
if (arguments.length > 0 && !!value) {
if (typeof value === "string") {
_lang = value;
} else if (typeof value === "boolean") {
_lang = value ? navigator.language
|| navigator.userLanguage
|| navigator.browserLanguage
|| navigator.systemLanguage
: defaultLang;
}
if (!!_lang) _lang = _lang.toString().toLowerCase();
} else {
if (_lang == null) lang(true);
}
return _lang;
}
因此,我们现在可以非常方便地获取或设置当前语言环境了。
// 假设当前处于简体中文环境 "zh-Hans"。
console.debug(Local.lang()); // zh-Hans
console.debug(Local.lang("en")); // en
console.debug(Local.lang()); // en
console.debug(Local.lang(true)); // zh-Hans
有了语言的获取和设置,我们要开始实现那个类了。
【未完待续】
文章类型及复杂度:Web 前端开发进阶。
节选翻译自 MSDN 博文 Localization in web page,内容有所调整。
http://blogs.msdn.com/b/kingcean/archive/2016/03/30/web-localization.aspx