【问题标题】:Infrastructure and internationalization for web app(s) using JSON only API使用仅 JSON API 的 Web 应用程序的基础架构和国际化
【发布时间】:2014-05-15 01:41:33
【问题描述】:

这是我打算构建的: 有一项服务通过 RESTful JSON-only API 提供数据。服务器设置为Python + Flask。 有几个客户端在使用此 API,例如普通的 Web 应用程序、移动兼容客户端和 Facebook 应用程序。

现在,我的假设/决定:

  • 我决定让服务器只通过JSON 提供数据,从而将演示文稿完全交给客户端。
  • 我希望使网络应用与移动设备兼容,从而无需单独的移动客户端。
  • 另外,对于 Facebook 应用程序,我决定使用 Facebook Canvas,它会渲染普通 Web 应用程序的一部分,从而重用代码。 如果上述假设有任何问题,请随时纠正我。以上虽然理论上是可行的,但我想知道实际的实现是否可行。

现在,Web 应用程序在从服务器获取基本页面/模板后,必须在通过 JSON API 获取数据后动态处理呈现。数据很简单:多选项问题,回答哪个用户收到另一个问题。最后,用户可以分享结果或邀请其他用户。

有了这个设置,我需要像angularjsjQuery 这样的框架就足够了吗?

我主要关心的是如何处理国际化?我最初打算使用Flask-Babel 来国际化 HTML 模板。但是,在只关注 JSON API 之后,我不知道我现在如何/在哪里处理它:在客户端还是服务器端?我使用什么工具?

我能想到的一种方法是在服务器本身上保存不同语言的数据,并根据客户端在请求中发送的某些属性,以适当的语言发送带有数据的 JSON 响应。

另一种方法是让客户端对服务器发送的公共数据集进行所有转换。不过我不确定这种方法。

【问题讨论】:

    标签: javascript internationalization flask single-page-application json-api


    【解决方案1】:

    你会发现 this 插件真的很有帮助。

    就使用而言,为由JSON API 提供支持的单页应用程序进行设置非常简单。

    如果我们看一下示例用法:

    HTML:

    <!DOCTYPE html>
    <html>
      <head>
        <script type="text/javascript" src="[PATH]/jquery.js" /> // optional
        <script type="text/javascript" src="[PATH]/i18next.js" />
      </head>
      <body>
        <ul class="nav">
          <li><a href="#" data-i18n="nav.home"></a></li>
          <li><a href="#" data-i18n="nav.page1"></a></li>
          <li><a href="#" data-i18n="nav.page2"></a></li>
        </ul>
      </body>
    

    Json(加载的资源):

    {
      "app": {
        "name": "i18next"
      },
      "nav": {
        "home": "Home",
        "page1": "Page One",
        "page2": "Page Two"
      }
    }
    

    JS:

    i18n.init(function(t) {
      // translate nav
      $(".nav").i18n();
    
      // programatical access
      var appName = t("app.name");
    });
    

    【讨论】:

      【解决方案2】:

      https://github.com/wikimedia/jquery.i18n 可能很接近。它可以处理很多语言,消息在json文件中,它是完整的客户端库。

      【讨论】:

        【解决方案3】:

        如果您的所有界面代码都位于客户端,那么您的 i18n.您将使用与您正在使用的 JavaScript 框架一起使用的 i18n 库。对于 Angular,可能是 angular-gettext

        如果您正在开发多个客户端,您可能会在不同的客户端应用程序中使用不同的 i18n 库。尽量确保他们都编译gettext .po files - 这会让你的翻译更容易。

        【讨论】:

          【解决方案4】:

          使用 jQuery、Angular 等是您应该根据您对技术的舒适度、应用程序的需求以及与 Facebook Canvas 方法的兼容性做出的决定。 Angular 具有强大的数据绑定功能,但与 jQuery 相比,它需要转变思维方式,因此我建议您仔细研究一下它们是否满足您的需求。

          至于国际化,你可以使用像 jQuery.i18n 这样的插件,或者你可以自己做,我用 jQuery 和 jQuery.Mustache 做模板。简短的版本是你使用 HTML 模板来存储你的布局,然后像这样从 jQuery 内部渲染它们:

          var data = {myLabel: 'Some label', myOtherLabel: 'Some Other Label'};
          
          $("#myDiv")
              .html( $.Mustache.render( "MyTemplateId", data ) );
          

          在html模板中:

          <script type="text/html" id="MyTemplateId">
              <div>
                  <label for="myInput">{{MyLabel}}</label> <input name="myInput" id="myInput type="text"/>
              <label for="myOtherInput">{{MyOtherLabel}}</label> <input name="myOtherInput" id="myOtherInput type="text"/>
          
              </div>
          

          在你的页面布局上:

          <div id="myDiv>
              <!-- dynamic content inserted here -->
          </div>
          

          您使用带有 jQ​​uery.Mustache (https://github.com/jonnyreeves/jquery-Mustache) 的加载器命令从服务器加载模板,并且由于您使用的是模板,因此您可以根据用户语言选择填写您的值。您如何存储国际化数据取决于您的应用程序。正如迈克尔建议的那样,如果它是少量的静态内容,也许您只需将它们作为常量存储在您的 JS 文件中,并根据需要加载到您的 Mustache 的 render() 方法中。如果您有大量/动态的多语言内容,您可能应该将其存储在服务器上并动态加载。一个考虑因素是您计划支持的语言数量。如果您超出少数几种语言,请考虑将其存储在服务器上并按需加载语言数据。

          我喜欢这种方法,因为它可以让您对布局和国际化进行精细的运行时控制。它还将数据存储在服务器上,但以编程方式从客户端加载,从而为您的应用程序层保持清晰的关注点分离。

          对于响应式/移动友好型设计,使用模板(Mustache)并在加载时检查视口可让您确定浏览器功能并提供适当的布局,而无需提示用户选择移动/桌面体验。

          如果你走这条路,你还应该研究像 RequireJS 和 StealJS 这样的脚本加载器来处理脚本的依赖加载,并处理初始浏览器检查和布局生成。

          【讨论】:

            【解决方案5】:

            你的问题太笼统了。我只能回答一部分,下面是一些答案:

            I desire to make the web app mobile compatible, thus eliminating need of a separate mobile client.
            

            为了确保一切正常,您需要处理

            Also, for Facebook app, I decided to use Facebook Canvas, which would render parts of the normal web app, thus reusing the code. 
            

            我不确定。

                With this setup, do I need a framework like angularjs or jQuery would suffice?
            

            正如您标记的那样,您将其定位为单页应用程序。因此,我建议您使用 Anglarjs、knockout.js 或 Node.js 等单页框架。可以从here找到这些框架之间的快速和良好的比较

            还有this的帖子分享了如何在Angularjs中实现国际化

               My main concern here is how do I handle internationalization? 
            

            其中一些框架为本地处理国际化和本地化提供了支持。对于其他人,您可以找到一些有助于实现国际化的链接。

            如果您使用 jQuery,您将定义自己的框架来处理单页应用程序,除此之外,您还需要大量的附加组件来实现您的目标。

            希望对你有帮助!!!

            【讨论】:

              【解决方案6】:

              通过js&json实现i18n的步骤:

              • 为 i18n 标签定义 css 类,例如&lt;span class="i18n" id="i18n_username"&gt;&lt;/span&gt;
              • 在不同的 .properties 文件中定义不同语言的 i18n 值,例如在 userhome_en_US.properties 中有一个键值:username = Username
              • 编写后端API,通过语言加载.properties文件,并以json键值格式返回,例如发送参数:lang=en_US, page=userhomeI18nAction -&gt; loadI18n(),然后通过ajax返回json值:{"username":"Username"}
              • 编写js函数,通过语言和页面参数加载i18n键值,
              • 更新网页上的 i18n 文本,通过 css 类获取标签,并替换内容,例如使用jquery获取所有带有class="i18n"的span标签,然后去掉id的i18n_前缀,然后用它作为key从返回的json中获取值,然后替换span的内容,

              我确实写过这样的实用程序,它非常灵活且易于使用。基本概念来源于struts2框架的i18n特性。

              【讨论】:

                【解决方案7】:

                虽然我不详细了解您的技术限制,但我相信这完全取决于您的数据量:

                • 如果您的“问题/答案”很少且可能不会随着时间的推移而发生很大变化,您可以将 I18N 视为常量。把一切都放在客户端是有意义的。

                • 如果您有大量可能会演变的“问题/答案”,我相信您必须将 I18N 视为数据

                既然您已经制作了 JSON API,那么您的 Q/A 很可能就是您的数据,并且它已经属于您的服务器端。

                真正的问题是:您是否希望每次添加或更正问题时都提供新版本的客户端应用程序?

                这就是我这样做的原因:

                我能想到的一种方法是在服务器本身上保存不同语言的数据,并根据客户端在请求中发送的某些属性,以适当的语言发送带有数据的 JSON 响应。

                编辑(精度):我说的是问题和答案。对于应用程序消息(菜单、文本、帮助消息等),您应该使用客户端框架的 i18n 组件。其他答案提供了很多很好的工具。

                【讨论】:

                  猜你喜欢
                  • 2018-07-04
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-01-29
                  • 2017-09-02
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多