代码之家  ›  专栏  ›  技术社区  ›  Ben Hall

Ruby on Rails的移动版视图

  •  15
  • Ben Hall  · 技术社区  · 15 年前

    我正在确认我做的是正确的事情。我的RubyonRails应用程序具有以下结构:


    关于.rhtml
    索引文件
    显示
    索引文件
    /data<--jquery从“显示\索引”页调用它,以提供要呈现的数据
    推JS.ERB
    荷兰皇家空军
    /布局
    HRTML
    显示.rhtml

    一切正常,但我现在想添加一个针对移动设备的网站。虽然iPhone能够正确呈现网站,但提供更具针对性的体验还是不错的。理想情况下,我正在考虑拥有一个iphone.domain.com,它将被重定向到via.htaccess。

    为此,我考虑为每个设备添加另一个视图。
    iPhone
    HRTML
    RHTML
    显示文件

    但是,感觉很多数据都会被复制,例如about页面有两个位置。我想我可以做一个部分渲染:部分=>'home/about',但这看起来有点老土。

    如何开发我的站点来支持这一点?

    我在考虑一种结构,比如,但又不确定如何构造代码-我该如何告诉它在iPhone目录中呈现视图…不应用主布局时
    显示
    iPhone
    索引文件

    我真的想要一些关于处理这个问题和构建应用程序的最佳方法的建议。虽然应用程序目前遵循一种结构,但它们可能朝着不同的方向发展。

    谢谢你

    4 回复  |  直到 10 年前
        1
  •  34
  •   Martin Kleppmann    15 年前

    我强烈建议在所有设备类型中保持控制器结构相同。尤其是当您使用Rails的RESTful路由时,您的控制器应该与数据的域模型紧密匹配。然后,这些数据是否会呈现给桌面浏览器、iPhone、不同类型的移动设备、JSON/XML REST API客户端等,主要取决于呈现层,而不是控制器/路由层。

    因此,一个优雅的解决方案是:

    1. 基于用户代理检测设备类型(可以参考WURFL用户代理数据库);
    2. 使用钢轨 respond_to 为每种设备类型呈现不同视图格式的机制;
    3. 为每种设备类型定义一个布局(例如,对移动设备使用xhtml mobile profile doctype);
    4. 根据设备类型包括不同的CSS文件。

    有一些插件试图使这更容易:看看布伦达林的mobile fu和诺埃尔拉平的rails iui(都在github上)。阿尔索 Brendan Lim's presentation at Rails Underground 有一些想法。

    你的目标应该是:

    def show
      @foo = Foo.find(params[:id])
      respond_to do |format|
        format.html       # => show.html.erb
        format.iphone     # => show.iphone.erb
        format.blackberry # => show.blackberry.erb
      end
    end
    

    如果移动设备上的用户真的希望看到站点的桌面版本,您还应该允许他们覆盖用户代理检测。一个具有较长失效时间的cookie可能是最好的方法,这样当用户下次返回时,站点就记住了选择。一些移动设备有垃圾cookie支持,但是他们可能无论如何都不想要这个网站的桌面版本,因为它可能不起作用。

        2
  •  9
  •   S. A.    10 年前

    Rails 4.1 包括 变体 一个伟大的新功能:

    允许您对相同的mime类型(例如,html)使用不同的模板和操作响应。对于任何为移动客户端服务的Rails应用程序来说,这都是一颗神奇的子弹。现在,在共享所有相同的控制器逻辑的同时,您可以拥有桌面、平板电脑和电话视图的单独模板。

    在您的情况下,只需在 before_action ,例如:

    class HomeController < ApplicationController
      before_action :detect_iphone
      def index
    
        respond_to do |format|
          format.html               # /app/views/home/index.html.erb
          format.html.phone         # /app/views/home/index.html+phone.erb
        end
      end
    
      private
        def detect_iphone
          request.variant = :iphone if request.user_agent =~ /iPhone/
        end
    end
    

    What's new in Rails 4.1

        3
  •  1
  •   Jonathon Horsman    15 年前

    实际上,iPhone可以很好地渲染没有任何特殊格式的网页。

    然而,在我的Android手机上,浮动内容似乎被切断了,所以需要为手机定制一个视图。 要实现这一点,您需要创建不同的布局(例如mobile_application.html.erb),并在应用程序_控制器中添加以下内容:

    layout :select_layout
    
      def select_layout
        session.inspect # force session load
        if session.has_key? "layout"
          return (session["layout"] == "mobile") ? "mobile_application" : "application"
        end
        return detect_browser
      end
    
      def detect_browser
        agent = request.headers["HTTP_USER_AGENT"].downcase
        MOBILE_BROWSERS.each do |m|
          return "mobile_application" if agent.match(m)
        end
        return "application"
      end
    

    其中mobile_浏览器是一组要与移动设备匹配的用户代理字符串。

    我在这里写了一篇关于这个的博客:

    http://www.arctickiwi.com/blog/2-mobile-enable-your-ruby-on-rails-site-for-small-screens

    干杯

        4
  •  0
  •   Omar Qureshi    15 年前

    首先,您应该使用.html.erb作为模板扩展名。

    其次,您可以使用逻辑来检测基于用户代理的布局类型。( request.user_agent )

    layout :site_layout
    
    def site_layout
      some_way_to_detect_the_layout_to_use
    end
    

    注意,用户代理可以被伪造,但大多数人不会费心去伪造它,所以解决方案应该“足够好”,适用于99.9%的情况。