Search code examples
ruby-on-railsrubyactionviewmustache

Rails 3.1 template handlers


I have a ruby gem, poirot, which enables the use of mustache templates in Rails. The template handler I have was extending from ActionView::Template::Handler, however this appears to be deprecated in Rails 3.1.

I have re-factored the handler to comply with the deprecation warnings. In doing this I am now unable to pass locals, or the view context, to the template. I can't seem to find out how to get this working with Rails 3.1.

module Poirot
  class Handler

    attr_reader :template

    def initialize(template)
      @template = template
    end

    def self.call(template, *args)
      self.new(template).call
    end

    def call
      view_path = "#{template.virtual_path}_view"
      abs_view_path = Rails.root.join('app/views', view_path)
      view_class = begin
        view_path.classify.constantize
      rescue NameError => e
        Poirot::View
      end
      "#{view_class}.new(self, '#{template.source.gsub(/'/, "\\\\'")}').render.html_safe"
    end
  end
end

In my code above for the handler I get passed the template, which is an instance of ActionView::Template. But I'm not sure how to get the view context, which should include the locals etc

Can someone point me in the right direction?


Solution

  • Okay I have a solution, I'm not sure it is the best, it feels a little hacky to me!

    In my view class I have managed to get access to the locals by doing the following:

    locals = view_context.send(:view_renderer).send(:_partial_renderer).instance_variable_get("@locals") || {}
    

    This feels a little messy as both view_renderer and _partial_renderer are private, and there is no proper accessor to the locals ivar.

    I'm still hoping there is a better way to do this!