开发者

How do I make a separate View path/directory for iPhone in Rails?

I'm making an iPhone version of an existing Rails app. I'd like to make the mobile version accessible via a subdomain such as iphone.mysite.com.

I know I can use formats and the respond_to block for individual erb files, such as index.iphone.erb as show here:

Creating an iPhone optimised version of your Rails site using iUI and Rails 2

But I'd like to keep entirely separate view directories for the mobile version and regular version such as this:

app/views/iphone

Here's what I've tried in my Application controller:

class ApplicationController < ActionController::Base
before_filter :set_site

def set_site
   subdomain=self.request.subdomains[0]
   ActionController::Base.prepend_view_path("app/views/#{subdomain}")
end

When testing this, however, the view switches to the view associated with the last requested subdomain by any user.

For example, if I visit http://iphone.mysite.com, then immediately go to http://www.mysite.com in another separate browser, I see the mobile version instead of the regular one. Refreshing it will correct this and bring up the right version. But if I go back to http://iphone.mysite.com in the other browser and refresh, it brings up the non-mobile site! I'm tearing my hair out and not understanding what's going on.

Any advice would be much appreciated.

Edit 1

Vlad below found a link with a possible solution however it is not working for me. Here is the code I tried. I made a file called subdomain_view.rb and placed it in config/initializers:

# Put all of this in a bootstrap-only initializer
ActionController::Base.class_eval do
  APP_ONE_VIEW_PATH = "app/views/iphone"
  APP_TWO_VIEW_PATH = "app/views/default"

  cattr_accessor  :application_view_path
  self.view_paths = ["app/views", APP_ONE_VIEW_PATH, APP_TWO_VIEW_PATH]

  # This is where you determine the switching mechanism for your application. Here, it is a simple GET parameter.
  # You can probably argue that this specific piece SHOULD be in your actual app_controller class definition, as it is the only piece
  # of info pertinent to the rest of your application.
  before_filter do |controller|
    ActionController::Base.application_view_path = request.subdomains[0]=="iphone" ? APP_TWO_VIEW_PATH : APP_ONE_VIEW_PATH
  end
end

require 'aquarium'
ActionView::PathSet.class_eval do
  include Aquarium::DSL
  before :find_templa开发者_如何学JAVAte do |join_point, object, *args|
    object.each_with_index do |path,i|
      object.unshift(object.delete_at(i)) if path.to_s == ActionController::Base.application_view_path
    end
  end
end
# I'll leave the exercise of testing this or implementing it for your particular app up to you.

With the above code, I am getting the same view no matter what subdomain I put in. Any suggestions on what might be wrong? Am I putting this code in the wrong place?


First, you have an error in your approach. You only 'set' a view path, you don't 'unset' it. When you do something like

ActionController::Base.prepend_view_path

this actually persists between your requests (internally, you are setting a class variable, and because classes are cached in production, this variable remains set between requests). Therefore, the current view path is the view path of your last request.

IMO, you should dynamically compute view_path for your current subdomain (this implies some ActionView hacking). A nice solution is provided here.


I was able to solve the problem by using a gem called themes_for_rails:

https://github.com/lucasefe/themes_for_rails

After installing the gem, here's what I added to my application files:

#application_controller.rb
class ApplicationController < ActionController::Base
  theme :theme_resolver
  def theme_resolver
      current_subdomain=self.request.subdomains[0]
  end
end


#routes.rb
MyAppName::Application.routes.draw do
  themes_for_rails
end


#Gemfile
gem 'themes_for_rails'

I placed my themes in [application_root]/themes. Make sure you don't put it in [application_root]/app/themes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜