开发者

Rails 3, find current view while in the layout

I have a scenario where I would like to have the name of the view that will be rendering while I'm in the layout file. I can find solutions to find which layout will be wrapping the current view from the view, but not the other wa开发者_如何学Pythony around. How can I find which view is rendering?


In Rails 3.0.3, I was able to see the name of the controller and action using controller_name and action_name. But those are not publicly documented (at least the action name) so I wouldn't depend on it long-term.

It might be better to monkey patch template render. In an initializer:

module ActionView::Rendering 
  alias_method :_render_template_original, :_render_template
  def _render_template(template, layout = nil, options = {}) 
    @last_template = template
    _render_template_original(template, layout, options)
  end
end

Then use @last_template in your layout.


The following solution works in Rails 3.1. Place this code in an initializer. (The rails 3.0.3 answer is not working any more in Rails 3.1)

This enables an @active_template variable for every controller. This is an instance of an ActionViewTemplate class.

The method active_template_virtual_path method returns the template as a name in the following form "controller/action"


    class ActionController::Base
      attr_accessor :active_template

      def active_template_virtual_path
        self.active_template.virtual_path if self.active_template
      end
    end

    class ActionView::TemplateRenderer 

      alias_method :_render_template_original, :render_template

      def render_template(template, layout_name = nil, locals = {})

        @view.controller.active_template = template if @view.controller
        result = _render_template_original( template, layout_name, locals)
        @view.controller.active_template = nil if @view.controller
        return result

      end
    end


I like the following approach, as you can reduce code size a good bit in a lot of cases. Include this in your application_controller.rb:

  before_filter :instantiate_controller_and_action_names
  caches_action :instantiate_controller_and_action_names

  def instantiate_controller_and_action_names
    @current_action = action_name
    @current_controller = controller_name
  end

Then, if your views correspond to an action, you just do:

dosomething if @current_action == 'new'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜