ruby-on-railsmobileruby-on-rails-4ruby-on-rails-3.2view-templates

Make Rails look for .mobile files in subdirectory?


I'm using the mobile fu gem to do some user-agent detection, so that I can serve either .html or .mobile extension templates depending on the client,

Now, this part works really good, but I don't like that view folders become a bit cluttered with twice the files, ie.

app/views/profiles/show.mobile.haml

app/views/profiles/show.html.haml

app/views/profiles/edit.mobile.haml

app/views/profiles/edit.html.haml

etc, etc

what I'd like to have instead is:

app/views/profiles/html/show.html.haml

app/views/profiles/html/edit.html.haml

And

app/views/profiles/mobile/show.mobile.haml

app/views/profiles/mobile/edit.mobile.haml

And have Rails automatically look into the correct folder/directory for files depending on the Request. Is this possible to do?

Maybe this is something really easy to do, let me know if this is a behavior that comes out of the box..

Thank you


Solution

  • Rails 4.1 has a new built-in feature called ActionPack Variants, which detects the user-agent (like the mobile fu gem).

    Basically, you can add this for example in your ApplicationController:

    before_action :detect_device_format
    
    private
    
    def detect_device_format
      case request.user_agent
      when /iPad/i
        request.variant = :tablet
      when /iPhone/i
        request.variant = :phone
      when /Android/i && /mobile/i
        request.variant = :phone
      when /Android/i
        request.variant = :tablet
      when /Windows Phone/i
        request.variant = :phone
      end
    end
    

    Let's say you have a ProfilesController. Now you can do this:

    class ProfilesController < ApplicationController
      def index
        respond_to do |format|
          format.html          # /app/views/profiles/index.html.erb
          format.html.phone    # /app/views/profiles/index.html+phone.erb
          format.html.tablet   # /app/views/profiles/index.html+tablet.erb
        end
      end
    end
    

    Back to your question: If you want to look for files in a different folder/directory, you can do this:

    format.html.phone { render 'mobile/index' }   # /app/views/mobile/index.html+phone.erb
    

    There is also a good tutorial which shows how to use it.