开发者

Rails 3.1 template handlers

开发者 https://www.devze.com 2023-03-27 06:43 出处:网络
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 R

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开发者_StackOverflow社区 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?


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!


I spent about 4 hours investigating source code to find a solution, and now it's seems very simple:

just add "local_assigns" where you are want to eval it and use.

For example:

"#{view_class}.new(self, '#{template.source.gsub(/'/, "\\\\'")}', local_assigns).render.html_safe"

this string will be evaluted inside the module context - ActionView::CompiledTemplates and local_assigns will be accessible there.

0

精彩评论

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

关注公众号