2009-08-16 13 views
15

Estoy buscando una validación de que estoy haciendo lo correcto. Tengo mi Ruby on Rails aplicación de la siguiente estructura:Versión móvil de vistas para Ruby on Rails

/home
      about.rhtml
      index.rhtml
/pantalla
      index.rhtml
/datos < - Esto es llamado por jQuery desde la página display \ index para proporcionar los datos a render
      push.js.erb
      pull.js.erb
/diseño
      home.rhtml
      display.rhtml

todo está funcionando bien, pero ahora desea agregar un sitio orientado para dispositivos móviles. Si bien el iPhone representa correctamente el sitio web, sería bueno proporcionar una experiencia más específica. Idealmente, estoy pensando en tener un iPhone.domain.com al que se redireccionaría a través de .htaccess.

Por esto, yo estaba pensando en añadir otro punto de vista para cada dispositivo
/iPhone
      home.rhtml
      about.rhtml
      display.rhtml

Sin embargo, parece que muchos de los datos estarían duplicados, por ejemplo, la página de aproximadamente estaría en dos lugares. Creo que podría tener un parcial y hacer algo así como render: partial => 'home/about', pero eso parece un poco hacky.

¿Cómo puedo desarrollar mi sitio para soportar esto?

Estaba pensando en una estructura como, pero una vez más no estoy seguro de cómo estructurar el código - cómo le digo que represente la vista en el directorio de iPhone ... mientras no se aplica el diseño maestro
/display
     /iphone
            index.rhtml

realmente me gustaría algún consejo sobre la mejor manera de abordar esto y estructurar la aplicación. Mientras que las aplicaciones siguen una estructura en el momento, que podrían ir en diferentes direcciones ..

Gracias

Ben

Respuesta

33

no te recomiendo dejar la estructura del controlador de la misma en todos los tipos de dispositivos. Particularmente si está utilizando las rutas RESTful de Rails, sus controladores deberían coincidir estrechamente con el modelo de dominio de sus datos. Si esos datos se presentan a un navegador de escritorio, a un iPhone, a un tipo diferente de dispositivo móvil, a un cliente de API REST JSON/XML, etc., es principalmente una cuestión de la capa de presentación, no del controlador/capa de enrutamiento.

Así que una solución elegante sería:

  1. detectar el tipo de dispositivo en función de agente de usuario (es posible que desee hacer referencia a la base de datos del agente de usuario WURFL);
  2. uso de Rails respond_to mecanismo para hacer Un formato de vista diferente para cada tipo de dispositivo;
  3. definir un diseño para cada tipo de dispositivo (por ejemplo, usando el Perfil de XHTML Mobile DOCTYPE para los dispositivos móviles);
  4. incluyen diferentes archivos CSS dependiendo del tipo de dispositivo.

Hay algunos complementos que intentan hacer esto más fácil: eche un vistazo a Mobile Fu de brendanlim y Rails iUI de noelrappin (ambos en GitHub). También Brendan Lim's presentation at Rails Underground tiene algunas ideas.

Lo que debe apuntar es algo así como:

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 

También debe permitir a los usuarios de los dispositivos móviles para anular la detección del agente de usuario si realmente quieren ver la versión de escritorio del sitio. Una cookie con un tiempo de caducidad largo es probablemente la mejor manera de hacerlo, de modo que el sitio recuerde la elección la próxima vez que regrese el usuario. Algunos dispositivos móviles tienen soporte para cookies basura, pero probablemente no querrán la versión de escritorio del sitio porque probablemente no funcionará.

+5

ambos rieles iUI y Mobile-Fu parece que no se han actualizado en un tiempo y no cuentan con el soporte adecuado de Rails 3. ¿Cuál es la última forma de manejar teléfonos móviles en Rails? – thermans

+0

He estado usando este tenedor de la gema mobile_fu: https://github.com/benlangfeld/mobile-fu Actualizado hace 2 meses y funciona para mis necesidades. – DemitryT

0

en primer lugar, usted debe utilizar .html.erb como su extensión de plantilla

En segundo lugar, puede usar la lógica para detectar el tipo de diseño que se va a utilizar en función del agente de usuario (request.user_agent).

layout :site_layout 

def site_layout 
    some_way_to_detect_the_layout_to_use 
end 

Nota, la user_agent puede ser falsificada, pero la mayoría de la gente no se molestan fingiendo lo que la solución debe ser "suficientemente bueno" para el 99,9% de los casos.

1

El Iphone realmente hace un buen trabajo de hacer que las páginas web sin ningún formato especial.

Sin embargo en mi teléfono Android flotaba contenido parece que se cortó y así se requiera una vista personalizada para ese teléfono. Para lograr esto es necesario para crear un diseño diferente (por ejemplo mobile_application.html.erb) y en su application_controller añadir lo siguiente:

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 

donde MOBILE_BROWSERS es un una matriz de cadenas de agente de usuario que desea hacer coincidir como dispositivo móvil.

escribí un blog sobre esto aquí:

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

Saludos

9

Rails 4.1 incluye variantes, una gran nueva característica que:

Le permite tener diferentes plantillas y respuestas de acción para el mismo tipo de mime (por ejemplo, HTML). Esta es una bala mágica para cualquier aplicación de Rails que esté sirviendo a clientes móviles. Ahora puede tener plantillas individuales para las vistas de escritorio, tableta y teléfono mientras comparte la misma lógica de controlador.

En su caso, sólo es necesario para establecer la variante para el iPhone en un before_action, por ejemplo:

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