Rails3 get current layout name inside view

2020-05-23 08:22发布

问题:

I have the answer for the Rails 2.X but not for Rails 3. How can I read the name of a current layout rendered inside a view.

My Rails2 question: Rails Layout name inside view

Thx.

回答1:

Getting this to work in Rails 3.2 is a little more complicated than previously outlined. If your controller explicitly declares a layout, then the result of controller.send(:_layout) is a String, but otherwise it's an ActionView::Template. Try this:

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


回答2:

For Rails 4:

controller.send(:_layout)
=> 'application'     

For Rails 3.2:

controller.send(:_layout)
=> #<ActionView::Template:0x000000082bb788> 

But controller.send(:_layout).identifier returns the fullpath:

/home/davidm/Documentos/Devel/myapp/app/views/layouts/application.haml


回答3:

I think it should be in core, but for now you can make a helper method:

 def current_layout
    controller.send :_layout
  end

it will return currently used layout name



回答4:

in rails 5

This works for me:

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


回答5:

I have used in Rails4 at view pages and got reuslt.

controller.send(:_layout)

I hope this help.



回答6:

For rails 5:

controller.class.send(:_layout)

This does NOT work:

controller.send(:_layout)


回答7:

You can do what I've done in my Ajax gem for Rails which is to wrap the _render_layout method:

    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

Then you can access the value that was set from your view (I'm pretty sure you have access to the controller there...) or in your controller in an after_filter, which is what I do.

I've written a custom RSpec 2 matcher which can be used to test layout rendering in Rails 3.



回答8:

All the approaches in the previous answers try to guess the name via private methods, but there's no need to guess and can be easily accomplished with the public API:

class ApplicationController
  layout :set_layout
  attr_reader :layout_name
  helper_method :layout_name

  private

  def set_layout
    @layout_name = "application"
  end
end

Override in any controller that won't use the standard layout:

class MyController < ApplicationController
  private

  def set_layout
    @layout_name = "my_layout"
  end
end

And now in your views:

<%= layout_name %>