Мне нужно то же самое. Я исследовал это, включая вопрос переполнения стека (и другой аналогичный вопрос), а также следил за потоком рельсов (как упоминалось в этом вопросе) на https://github.com/rails/rails/issues/3855 и следовал за его потоками / гистами / драгоценными камнями.
Вот то, что я закончил, работает с Rails 3.1 и движками. Это решение позволяет вам размещать * .mobile.haml (или * .mobile.erb и т. Д.) В том же месте, что и другие файлы просмотра, без необходимости в двух иерархиях (одна для обычной и одна для мобильных).
Код двигателя и приготовления
в моем «базовом» движке я добавил это в config/initializers/resolvers.rb
:
module Resolvers
# this resolver graciously shared by jdelStrother at
# https://github.com/rails/rails/issues/3855#issuecomment-5028260
class MobileFallbackResolver < ::ActionView::FileSystemResolver
def find_templates(name, prefix, partial, details)
if details[:formats] == [:mobile]
# Add a fallback for html, for the case where, eg, 'index.html.haml' exists, but not 'index.mobile.haml'
details = details.dup
details[:formats] = [:mobile, :html]
end
super
end
end
end
ActiveSupport.on_load(:action_controller) do
tmp_view_paths = view_paths.dup # avoid endless loop as append_view_path modifies view_paths
tmp_view_paths.each do |path|
append_view_path(Resolvers::MobileFallbackResolver.new(path.to_s))
end
end
Тогда в контроллере приложения моего «базового» движка я добавил мобильный? Метод:
def mobile?
request.user_agent && request.user_agent.downcase =~ /mobile|iphone|webos|android|blackberry|midp|cldc/ && request.user_agent.downcase !~ /ipad/
end
А также это before_filter
:
before_filter :set_layout
def set_layout
request.format = :mobile if mobile?
end
Наконец, я добавил это к config/initializers/mime_types.rb
:
Mime::Type.register_alias "text/html", :mobile
Использование
Теперь я могу иметь (на уровне приложения или в движке):
app/views/layouts/application.mobile.haml
- и в любом представлении
.mobile.haml
вместо .html.haml
файла.
Я даже могу использовать определенную мобильную раскладку, если я установлю ее на любом контроллере:
макет "мобильный"
, который будет использовать app/views/layouts/mobile.html.haml
(или даже mobile.mobile.haml
).