这个问题是我之前未回答的问题的后续:ActionView::MissingTemplate: Missing template (Trying to render nonexistent :mobile format)
由于这似乎不是 Rails 方法的共识,有什么方法可以在格式不可用:html
时从移动设备访问以呈现默认值?:mobile
(如果存在:mobile
视图,则应优先于非移动格式的视图)。
这个问题是我之前未回答的问题的后续:ActionView::MissingTemplate: Missing template (Trying to render nonexistent :mobile format)
由于这似乎不是 Rails 方法的共识,有什么方法可以在格式不可用:html
时从移动设备访问以呈现默认值?:mobile
(如果存在:mobile
视图,则应优先于非移动格式的视图)。
假设您有一个mobile_request?
控制器实例方法来检测移动请求,那么您应该能够设置格式回退链:
# application_controller.rb
before_filter :set_request_format, :set_format_fallbacks
respond_to :html, :mobile # etc
def set_request_format
request.format = :mobile if mobile_request?
end
def set_format_fallbacks
if request.format == :mobile
self.formats = [:mobile, :html]
end
end
这应该可行,但显然并不完全。 https://github.com/rails/rails/issues/3855 如果你有一个移动模板,格式似乎被锁定,它不会找到只有 html 的部分。
希望它会以某种方式修复。同时,您可以将此 <% controller.set_format_fallbacks %> 放入每个模板(哎哟)或编写自己的解析器。 http://jkfill.com/2011/03/11/implementing-a-rails-3-view-resolver/
还请看:
我需要同样的东西。我对此进行了研究,包括这个堆栈溢出问题(以及另一个类似的问题),并遵循了https://github.com/rails/rails/issues/3855上的 rails 线程(如本问题中所述)并遵循了它的线程/要点/宝石。
这就是我最终使用 Rails 3.1 和引擎所做的工作。此解决方案允许您将 *.mobile.haml(或 *.mobile.erb 等)放置在与其他视图文件相同的位置,而无需 2 个层次结构(一个用于常规,一个用于移动)。
在我的“基础”引擎中,我添加了这个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
文件。如果我在任何控制器中设置它,我什至可以使用特定的移动布局: layout 'mobile'
这将使用app/views/layouts/mobile.html.haml
(甚至mobile.mobile.haml
)。
尝试这个:
if File.exists?('app/views/object/mobile.file.erb')
render :mobile
else
render :html
end