Ruby on Rails的移动版本视图

Ben*_*all 15 iphone mobile ruby-on-rails windows-mobile

我经过一些验证后说我做对了.我有以下结构中的Ruby on Rails应用程序:

/ home
   about.rhtml
   index.rhtml
/ display
   index.rhtml
/ data < - 这是由jQuery从display\index页面调用来提供数据来呈现
   push.js.erb
   pull.js.erb
/ layout
   home.rhtml
   display.rhtml

一切都运行良好,但我现在想要添加一个针对移动设备的网站.虽然iPhone正确呈现网站,但提供更有针对性的体验会很不错.理想情况下,我正在考虑拥有一个可以通过.htaccess重定向到的iPhone.domain.com.

为此,我考虑为每个设备
/ iPhone
   home.rhtml 添加另一个视图
   about.rhtml
   display.rhtml

但是,感觉很多数据会被复制,例如,关于页面将在两个地方.我想我可以有一个局部并做一些像渲染:partial =>'home/about'但这看起来有点像hacky.

如何开发我的网站以支持此功能?

我在想一个像这样的结构,但又不知道如何构造代码 - 如何告诉它在iPhone目录中呈现视图...而没有应用主布局
/ display
   / iphone
      index.rhtml

我真的想要一些关于最佳方法的建议,并构建应用程序.虽然应用程序目前遵循一种结构,但它们可能会朝不同的方向发展.

谢谢

Mar*_*ann 34

我强烈建议在所有设备类型中保持控制器结构相同.特别是如果您使用Rails的RESTful路由,您的控制器应该与数据的域模型紧密匹配.然后将数据呈现给桌面浏览器,iPhone,不同类型的移动设备,JSON/XML REST API客户端等,主要是表示层,而不是控制器/路由层.

所以优雅的解决方案是:

  1. 检测基于用户代理的设备类型(您可能需要参考WURFL用户代理数据库);
  2. 使用Rails的respond_to机制为每种设备类型呈现不同的视图格式;
  3. 为每种设备类型定义布局(例如,为移动设备使用XHTML Mobile Profile doctype);
  4. 根据设备类型包含不同的CSS文件.

有一些插件试图让这更容易:看看brendanlim的Mobile Fu和noelrappin的Rails iUI(都在GitHub上).此外布伦丹Lim的在Rails的地下呈现有一些想法.

你应该瞄准的是:

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
Run Code Online (Sandbox Code Playgroud)

如果他们确实想要查看站点的桌面版本,您还应该允许移动设备上的用户覆盖用户代理检测.具有较长到期时间的cookie可能是执行此操作的最佳方式,以便站点在下次用户返回时记住该选择.一些移动设备有垃圾cookie支持,但他们可能不会想要该网站的桌面版本,因为它可能无法正常工作.

  • Rails iUI和Mobile-Fu似乎都没有在一段时间内更新,并且没有适当的Rails 3支持.在Rails中处理手机的最新方法是什么? (5认同)

Ser*_* A. 9

Rails 4.1包含Variants,这是一个很棒的新功能:

允许您为相同的mime类型(例如,HTML)使用不同的模板和操作响应.这是任何为移动客户端提供服务的Rails应用程序的灵丹妙药.您现在可以拥有桌面,平板电脑和手机视图的各个模板,同时共享所有相同的控制器逻辑.

在您的情况下,您只需要在a中设置iphone的变体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
Run Code Online (Sandbox Code Playgroud)

Rails 4.1中有什么新功能