i18n:在JavaScript中访问区域设置解析逻辑

时间:2015-02-12 16:50:00

标签: javascript localization internationalization single-page-application

我正在使用2种本地化文本开发和国际化单页应用程序:

  1. '静态'文本,通常是我的HTML模板中的文本。
  2. '动态' text,,即生活在数据库中的文本,通常是电子商务网站上产品的描述。
  3. 它的类型2我遇到了麻烦。假设我的应用程序正式支持英语,法语和德语,我从数据库中获取了一个对象,例如:

    {
      description: {
        'en': "It's an awesome product.",
        'en_UK': "This product is ace.",
        'fr': "C'est un excellent produit."
        // German's missing
      }
    }
    

    现在的挑战是动态选择应该选择显示的区域设置,给定用户的区域设置以及此特定对象中可用的区域设置。

    我认为大多数i18n JavaScript库都有自己的'语言环境解析'逻辑内置,但我没有找到一个暴露这个逻辑供客户使用。

    有没有人知道解决这个问题的JS库,或者解决这个问题的好方法? (如果它与AngularJs兼容,那么&#39 ;甚至更好。)

    提前致谢!

2 个答案:

答案 0 :(得分:2)

  

免责声明:我是L20n的合着者之一,也是L20n的开发者之一   l10n.js在Firefox OS中使用。

通常用于描述此逻辑的术语是语言协商

大多数本地化库应该包含某种语言协商算法。它可以像尝试将navigator.language的值与可用语言列表相匹配一样基本。更复杂的方法将查看语言标记(en中的en-US)和区域标记(US中的en-US),以尝试找到最佳匹配。

ECMAScript的Intl对象上有一个proposal to expose a language negotiation method,但是现在为此目的不可能使用其内部逻辑。

获取用户首选的语言列表并不容易。大多数浏览器中都有navigator.language(这是Firefox中的用户首选语言和language of the browser UI in Chrome),Internet Explorer中有navigator.userLanguage,新的navigator.languages是有序列表用户的首选语言。

服务器端替代方案是使用HTTP请求的Accept-Language标头,这是查找用户偏好的最可靠方式。

获得用户首选语言列表后,即可执行语言协商。

以下是执行语言协商的一些库示例:

对于您的特定用例,您可以选择执行以下两项操作之一:

  1. 使用navigator.language || navigator.userLanguage在客户端执行语言协商,并向数据库发送请求,指定您感兴趣的语言,或

  2. 使用用户的Accept-Language标头发送请求,并在服务器端执行语言协商,然后在数据库中查询正确的翻译。

  3. 这两种解决方案的好处是,当最终只使用一个解决方案时,不会将整套翻译发送到客户端。

    对于解决方案#1,假设您正在使用Angular,我可以建议使用L20n 1.0.x通过ng-l20n module与Angular集成。您应该能够使用supportedLocales property获取协商的语言列表,并使用该列表的第一个元素来查询数据库。

    对于解决方案#2,这一切都取决于您的服务器端设置,但如果您使用的是node.js,则可以尝试使用以下模块之一:

答案 1 :(得分:1)

StaśMałolepszy的answer是此问题域可用资源的良好参考。

但是,我发现这些库中没有一个适合我的需求(因为它们的语言协商逻辑太简单了,或者因为它没有真正公开)。

因此,我实现了自己的语言协商自定义解决方案。您可以在this Plunkr: http://plnkr.co/edit/Cfv49ZcQWJcqwOXYcjtw?p=preview

中进行试验

API是一个函数negotiate(availableLocales, requestedLocales, defaultLocale),有点类似于ECMAScript proposal(不同之处在于它返回单个区域设置值,而不是列表)。

// simple cases
negotiate(["fr"], ["de","fr"], 'en'); // => fr
negotiate(["en"], ["de","en-US","en"], 'en'); // => en

// less natural cases, where the solution is more opinionated
negotiate(["fr-FR"], ["fr"], 'en'); // => fr-FR
negotiate(["en","en-UK","fr"], ["fr-FR"], 'en'); // => fr
negotiate(["fr","de"], ["fr-FR","de"], 'en'); // => fr

我选择以非平凡的,自以为是的方式解释“区域设置继承”(例如en-US来自en)。我并不认为这符合该主题的任何标准。

令我感到惊讶的是,我找不到任何提供此类功能的库。我最好的解释是,经常不需要i18​​n的动态内容。

最后,至于我获取所请求语言的列表,就像我在单页应用程序配置中一样,我选择向服务器发送一个AJAX请求,并在响应中包含Accept-Language标头的内容。 / p>