我正在使用2种本地化文本开发和国际化单页应用程序:
它的类型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 ;甚至更好。)
提前致谢!
答案 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
标头,这是查找用户偏好的最可靠方式。
获得用户首选语言列表后,即可执行语言协商。
以下是执行语言协商的一些库示例:
Intl
的ECMA-402 Intl.prioritizeLocales
对象non-standard extension。对于您的特定用例,您可以选择执行以下两项操作之一:
使用navigator.language || navigator.userLanguage
在客户端执行语言协商,并向数据库发送请求,指定您感兴趣的语言,或
使用用户的Accept-Language
标头发送请求,并在服务器端执行语言协商,然后在数据库中查询正确的翻译。
这两种解决方案的好处是,当最终只使用一个解决方案时,不会将整套翻译发送到客户端。
对于解决方案#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
)。我并不认为这符合该主题的任何标准。
令我感到惊讶的是,我找不到任何提供此类功能的库。我最好的解释是,经常不需要i18n的动态内容。
最后,至于我获取所请求语言的列表,就像我在单页应用程序配置中一样,我选择向服务器发送一个AJAX请求,并在响应中包含Accept-Language标头的内容。 / p>