【问题标题】:Phonegap/Cordova internationalization supportPhonegap/Cordova 国际化支持
【发布时间】:2012-01-16 09:34:18
【问题描述】:

我正在使用 Phonegap 开发移动应用程序,我需要国际化 - 以不同语言显示 html 页面。我现在明白这不是 Phonegap 问题 - 我必须将 Web 应用程序国际化。

  • 是否有任何框架支持国际化(例如 jQuery Mobile)?
  • 是否可以使用模板方法,例如在构建过程中使用属性文件和模板并生成 HTML?`
  • 如果我使用 Bourbon 的方法(请参阅答案),如何根据选项设置切换语言?

问候,克里斯蒂安

--- 编辑 --

Phonegap 从 2.2.0 开始就有一个不错的全球化插件。它涵盖了很多 i18n 功能。查看文档http://docs.phonegap.com/en/edge/cordova_globalization_globalization.md.html#Globalization

【问题讨论】:

  • 我今天开始开发 Cordova 应用程序时也在寻找同样的东西。 CPU 资源在某些手机上是有限的,因此我想尽量减少 JavaScript。我投票支持模板方法 - 在客户端手机上会更轻松。
  • 这个插件与语言无关,它只是返回浏览器当前的语言,但我们可以将i18n用于不同的语言

标签: cordova


【解决方案1】:

I took an approach to this problem that allows others to contribute language translations for my application.

优点:

  • 使用“网络成熟”的库
  • 众包翻译
  • 没有原生黑客攻击
  • 使用模板
  • 非常容易实现 HTML/JS 并且易于测试
  • 支持语言检测
  • 支持文本方向 (BiDi)
  • 完全没有原生依赖,因此可以在 Android/iOS/BB/WP yada yada..
  • 可在网络浏览器中测试

缺点:

  • 您的项目需要开源并满足 TranslateWiki 的要求
  • 如果您来自分支/合并世界,实现对 Gerrit 的提交会有点棘手。

我使用handlebars 进行模板化,使用html10n 库提供翻译逻辑,翻译后的字符串来自社区贡献的json 文件。

TranslateWiki 通过众包的力量提供实际的翻译。我实现的大部分繁重工作由 TranslateWiki 完成,这是一个来自 Wiki Media Foundation 的免费开源社区服务。

Handlebars 和 html10n 库功能强大,专为 Web 构建并被广泛使用。它们被证明是非常有用的库。

不需要本机代码或插件。

index.html

<head>
  <script type="text/javascript" src="js/handlebars.js"></script>
  <script type="text/javascript" src="js/html10n.js"></script>
  <link rel="localizations" type="application/l10n+json" href="locales.json">
</head>
<body>
    {{html10n "helloWorld"}}
</body>

locales.json

{
  "fr":"locales/fr.json",
  "en":"locales/en.json"
}

locales/en.json

{
  "en":{
    "helloWorld":"Hello Cruel World"
  }
}

locales/fr.json

{
  "fr":{
    "helloWorld":"Hello Baguette World"
  }
}

index.js

Handlebars.registerHelper('html10n', function(str,a){
  return (html10n != undefined ? html10n.get(str) : str);
});

要在语言之间切换,请打开浏览器的 javascript 控制台并输入

html10n.localize("fr");

进行浏览器语言检测需要一些额外的逻辑,我使用 Etherpad 的实现来完成。

var language = document.cookie.match(/language=((\w{2,3})(-\w+)?)/);
if(language) language = language[1];
html10n.bind('indexed', function() {
  html10n.localize([language, navigator.language, navigator.userLanguage, 'en'])
})
html10n.bind('localized', function() {
  document.documentElement.lang = html10n.getLanguage()
  document.documentElement.dir = html10n.getDirection()
  // Then I display the index page using handlebars to render a template.
});

就是这样,在您的 Cordova 应用程序中推出 i18n 的免破解秘诀。

【讨论】:

  • 嘿,我可以使用它吗?我不需要将把手的东西放在模板中,编译,渲染等?
  • 这个答案值得大量的支持Hello Baguette World
【解决方案2】:

Phonegap 只是一个框架,能够在原生应用中显示网页,并使用一些插件连接设备的硬件传感器。对国际化的支持将取决于您的 html/js 设计。

例如,您可以使用:

/html/en/index.html
/html/fr/index.html
...

并根据用户的语言调用好页面。

希望这会对你有所帮助:-)

【讨论】:

  • "并根据用户的语言调用好页面。"如何分辨用户的语言?
【解决方案3】:

我完全按照 Bourbon 的建议做了,因为它是一个小应用程序,重复不是问题。 不过也有模板框架,我觉得用的最多的是mustache

我解决了这样的语言选择:

@Override
public void onCreate(final Bundle savedInstanceState)
{
    // ...
    String language = getValue("language", "de");
    if (language.equals("de")) {
        super.loadUrl("file:///android_asset/www/de/index.html", 1);
    }
    else {
        super.loadUrl("file:///android_asset/www/en/index.html", 1);
    }
}

private String getValue(final String key, final String defaultValue)
{
    SharedPreferences prefs = getSharedPreferences(
            getApplicationInfo().packageName, MODE_PRIVATE);
    return prefs.getString(key, defaultValue);
}

如您所见,我从 SharedPreferences 中读取了值。我还创建了一个 Phonegap 插件,以便在用户更改语言时从 JavaScript 代码设置此值。

【讨论】:

    【解决方案4】:

    这是我非常简单的解决方案。我在我的 APP 中使用 jQuery,然后将 class="lang" 添加到包含应该翻译的字符串的所有元素中,并添加到相同的元素中:

    • data-lang="变量"
    • data-lang-to="receive"

    例如:

    <input type="search" placeholder="Search..." class="lang" data-lang="search" data-lang-to="placeholder" />
    

    这是我的课:

    var localize={
        locals: {
            'it': {
                click_activation: 'clicca qui per ricevere il codice di attivazione',
                search: "Cerca..."
            },
            'en-us': {
                click_activation: 'click here to re-send the activation code',
                search: "Search User..."
            }
        },
        start: function(lang){
            lang=lang.toLowerCase();
            var langs=this.locals;
            $('.lang').each(function(){
                var txt=$(this).data('lang');
                var to=$(this).data('lang-to');
                if(txt!==''&&typeof langs[lang][txt]!=='undefined'){
                    switch(to){
                        case 'text':
                            $(this).text(langs[lang][txt]);
                            break;
                        case 'placeholder':
                        case 'alt':
                        case 'title':
                            $(this).attr(to, langs[lang][txt]);
                            break;
                        case 'html':
                        default:
                            $(this).html(langs[lang][txt]);
                            break;
                    }
                }
            });
        }
    };
    
    localize.start(lang); //use phonegap globalization to discover this one if you want
    

    【讨论】:

      【解决方案5】:

      我基于@ChrLipp 采取了不同的方法

      super.loadUrl("file:///android_asset/www/index.html?lang=" + lang);
      

      然后我有一个 js 脚本,它根据查询字符串中提供的语言加载正确的文件

      (function() {
          var lang;
          try {
              lang = RegExp('[?&]lang=([^&]*)').exec(window.location.search)[1];
          } catch (ex) {
              lang = "es";
          }
          document
                  .write(unescape("%3Cscript type='text/javascript' src='locale/angular-locale_"
                          + lang + ".js'%3E%3C/script%3E"));
          document
                  .write(unescape("%3Cscript type='text/javascript' src='locale/i18n_"
                          + lang + ".js'%3E%3C/script%3E"));
      })();
      

      使用这种方法可以轻松扩展。

      写完这个答案后,我发现了一个更好的方法,只使用js:

      lang = navigator.language.split('-')[0];
      

      Mozilla developer, navigator

      这解决了编写代码以在不同平台(例如 iOS)中获取语言环境的问题。

      希望对你有帮助

      【讨论】:

      • 这将在 WP8 上失败,因为 ?在 URL 中,您需要使用 #?
      【解决方案6】:

      如果像我这样的人想知道,为什么这么简单的任务没有现成的解决方案:jQuery.localize 可以解决您的问题。

      1. &lt;script type="text/javascript" src="jquery.localize.js"&gt;&lt;/script&gt; 添加到您的索引 html 文件中
      2. 为可本地化的 html 对象添加标签:&lt;h1 data-localize="greeting"&gt; Hello! &lt;/h1&gt;
      3. localization-ru.json 添加到您的项目中:

        { "greeting": "Привет!" }

      我已将其添加到 system/localization/localization-ru.jsonru 后缀是文件的语言(例如,俄语)。您可能需要localization-en.jsonlocalization-de.json 等:

      1. 'deviceready'事件回调监听器添加语言加载和html页面更新:

        $("[data-localize]").localize("system/localization/localization")

      2. 对于javascript字符串的本地化如下:

        $.localize.data.["system/localization/localization"]["greeting"];
        

      "system/localization/localization" 是从 www 文件夹到您的本地化.json 的路径,您可能会为它编写一个快捷方式(第一次和最后一次您实际上需要编写代码)。

      【讨论】:

        【解决方案7】:

        我找不到任何框架来做这个,所以我开始了我自己的插件。 我只想写一个 html 并让 strings.xml 进行国际化(我现在只对 android 感兴趣)。

        看看它,它可能会帮助你: https://github.com/zeitos/i18nplugin

        【讨论】:

          【解决方案8】:

          我正在开发一个 Cordova-AngularJS 应用程序。 我采取了以下简单的方法。 使用服务进行实际翻译:

          angular.module('App.services.Localization', [])
          
          .factory('__', ['$window', function(window){
            var lang = navigator.language.split('-')[0];
            console.log('lang: ' + lang);
            //default language
            var default_language = 'de';
          
            return function(string) {
                var lang_json = window['__' + lang];
                var loc_str = "";
                if(lang_json === undefined){
                  //use default lang
                  loc_str = window["__" + default_language][string];
                }else{
                  loc_str = window["__" + lang][string];
                }
          
                return loc_str;
            };
          
          }]);
          

          我在全局 Window 范围内为我在应用程序中支持的每种语言都包含了一个 JSON-Object。例如:

          var __de = {
            'Speisekarte' : 'Speisekarte',
            'Löschen'     : 'Löschen'
          }
          

          var __en = {
            'Speisekarte' : 'Menu',
            'Löschen'     : 'Delete'
          }
          

          您可以轻松地为每种语言使用一个 JS 文件来保存相应的 JSON 对象。

          这样服务可以访问像

          这样的对象
          window['__' + lang]
          

          并返回翻译后的字符串。

          现在要做的就是将服务及其方法 -getString 注入每个需要本地化静态字符串的控制器。您还必须引用本地范围 var 才能在模板文件中使用本地化。

          在控制器内部设置的字符串和模板文件中的字符串通过

          __("stringToBeTranslated");
          

          这是一个控制器示例:

          angular.module('App.controllers.Menu', [
            'App.services.Localization'
          ])
          
          .controller('MenuController', ['$scope', '__', function(scope, __) {
          
            //...
            //pass the Localization service __(string)-Method to the local scope to be used in Template-Files
            scope.__ = __;
          
            //...
          }]);
          

          【讨论】:

            【解决方案9】:

            您是否尝试过使用ionic 框架?

            【讨论】:

            • 你用什么来内化和离子?你推荐i18n Ionic吗?
            • Ionic 是最好的选择
            • @RicardoCruz 我对 ionic1 使用 angular-translate,对 ionic2 及更高版本使用 ngx-translate 来创建效果。
            猜你喜欢
            • 1970-01-01
            • 2016-11-06
            • 1970-01-01
            • 1970-01-01
            • 2013-10-14
            • 2012-06-06
            • 2021-03-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多