在Rails 3.2中使用它比以前概述的要复杂一些。如果你的控制器显式声明了一个布局,那么controller.send(:_layout)
的结果就是一个String,但是它是一个ActionView :: Template。试试这个:
module ApplicationHelper
def current_layout
layout = controller.send(:_layout)
if layout.instance_of? String
layout
else
File.basename(layout.identifier).split('.').first
end
end
end
对于Rails 4:
controller.send(:_layout)
=> 'application'
对于Rails 3.2:
controller.send(:_layout)
=> #<ActionView::Template:0x000000082bb788>
但controller.send(:_layout).identifier
返回完整路径:
/home/davidm/Documentos/Devel/myapp/app/views/layouts/application.haml
我认为它应该是核心的,但是现在你可以制作一个帮助方法:
def current_layout
controller.send :_layout
end
它将返回当前使用的布局名称
在轨道5
这对我有用:
def current_layout
layout = controller.class.send(:_layout)
if layout.nil?
default_layout
elsif layout.instance_of? String or layout.instance_of? Symbol
layout
else
File.basename(layout.identifier).split('.').first
end
end
你可以做我在Ajax gem for Rails中所做的事情,即包装_render_layout
方法:
ActionView::Base.class_eval do
def _render_layout_with_tracking(layout, locals, &block)
controller.instance_variable_set(:@_rendered_layout, layout)
_render_layout_without_tracking(layout, locals, &block)
end
alias_method_chain :_render_layout, :tracking
end
然后你可以访问从视图中设置的值(我很确定你可以访问那里的控制器......)或者在你的控制器中访问after_filter
,这就是我的工作。
我写了一个custom RSpec 2 matcher,可以用来测试Rails 3中的布局渲染。
之前答案中的所有方法都试图通过私有方法猜测名称,但是没有必要猜测,并且可以使用公共API轻松完成:
class ApplicationController
layout :set_layout
attr_reader :layout_name
helper_method :layout_name
private
def set_layout
@layout_name = "application"
end
end
在任何不使用标准布局的控制器中覆盖:
class MyController < ApplicationController
private
def set_layout
@layout_name = "my_layout"
end
end
现在在你的观点中:
<%= layout_name %>
对于导轨5:
controller.class.send(:_layout)
这不起作用:
controller.send(:_layout)