Как сделать отдельный путь / каталог View для iPhone в Rails? - PullRequest
0 голосов
/ 16 ноября 2010

Я делаю версию iPhone для существующего приложения Rails. Я хотел бы сделать мобильную версию доступной через поддомен, такой как iphone.mysite.com.

Я знаю, что могу использовать форматы и блок response_to для отдельных файлов erb, например index.iphone.erb, как показано здесь:

Создание оптимизированной для iPhone версии вашего сайта Rails с использованием iUI и Rails 2

Но я бы хотел сохранить совершенно разные каталоги просмотра для мобильной версии и обычной версии, например:

app/views/iphone

Вот что я попробовал в моем контроллере приложений:

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

Однако при тестировании это представление переключается на представление, связанное с последним запрошенным поддоменом любым пользователем.

Например, если я захожу на http://iphone.mysite.com, а затем сразу перехожу на http://www.mysite.com в другом отдельном браузере, я вижу мобильную версию вместо обычной. Обновление исправит это и выведет правильную версию. Но если я вернусь к http://iphone.mysite.com в другом браузере и обновлю, он откроет немобильный сайт! Я вырываю волосы и не понимаю, что происходит.

Любой совет будет высоко ценится.

Редактировать 1

Влад ниже нашел ссылку с возможным решением, но оно не работает для меня. Вот код, который я попробовал. Я сделал файл с именем subdomain_view.rb и поместил его в 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_template 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.

С помощью приведенного выше кода я получаю одно и то же представление независимо от того, в какой поддомен я вставляю. Любые предложения о том, что может быть не так? Я помещаю этот код в неправильное место?

Ответы [ 2 ]

0 голосов
/ 16 ноября 2010

Мне удалось решить проблему с помощью гема themes_for_rails:

https://github.com/lucasefe/themes_for_rails

После установки гема вот что я добавил в файлы своего приложения:

#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'

Я разместил свои темы в [application_root]/themes.Убедитесь, что вы не вставили это в [application_root]/app/themes.

0 голосов
/ 16 ноября 2010

Во-первых, у вас есть ошибка в вашем подходе. Вы только «устанавливаете» путь просмотра, вы не «отменяете» его. Когда вы делаете что-то вроде

ActionController::Base.prepend_view_path

это фактически сохраняется между вашими запросами (внутренне вы устанавливаете переменную класса, и поскольку классы кэшируются в рабочей среде, эта переменная остается установленной между запросами). Поэтому текущий путь просмотра - это путь просмотра вашего последнего запроса.

IMO, вы должны динамически вычислять view_path для вашего текущего субдомена (это подразумевает некоторый взлом ActionView). Хорошее решение предоставляется здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...