4

这个问题是我之前未回答的问题的后续:ActionView::MissingTemplate: Missing template (Trying to render nonexistent :mobile format)

由于这似乎不是 Rails 方法的共识,有什么方法可以在格式不可用:html时从移动设备访问以呈现默认值?:mobile(如果存在:mobile视图,则应优先于非移动格式的视图)。

4

3 回答 3

3

假设您有一个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/

还请看:

移动 mime 类型可以在 Rails 中回退到“html”吗?

在 rails 3.1 中更改视图格式(提供移动 html 格式,回退到普通 html)

于 2012-05-22T18:16:42.443 回答
0

我需要同样的东西。我对此进行了研究,包括这个堆栈溢出问题(以及另一个类似的问题),并遵循了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
  • 并且在任何视图中都是 a.mobile.haml而不是.html.haml文件。

如果我在任何控制器中设置它,我什至可以使用特定的移动布局: layout 'mobile'

这将使用app/views/layouts/mobile.html.haml(甚至mobile.mobile.haml)。

于 2013-03-31T17:57:56.997 回答
0

尝试这个:

if File.exists?('app/views/object/mobile.file.erb')
  render :mobile
else
  render :html
end
于 2012-05-22T17:31:33.423 回答