2011-08-11 17 views
5

Tengo una gema de rubí, poirot, que permite el uso de plantillas de bigote en Rails. El manejador de plantillas que tengo se extendía desde ActionView :: Template :: Handler, sin embargo, esto parece estar en desuso en Rails 3.1.Controladores de plantilla Rails 3.1

He vuelto a factorizar el controlador para cumplir con las advertencias de desactivación. Al hacer esto, ahora no puedo pasar los locales, o el contexto de la vista, a la plantilla. Parece que no puedo encontrar la manera de hacer que esto funcione con 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 

En mi código de seguridad para el controlador que van pasando la plantilla, que es una instancia de ActionView :: Plantilla. Pero no estoy seguro de cómo obtener el contexto de vista, que debe incluir los locales, etc.

¿Alguien puede indicarme la dirección correcta?

Respuesta

0

Bien, tengo una solución, no estoy seguro de que sea la mejor, ¡se siente un poco hacky para mí!

En mi clase de vista que he logrado conseguir el acceso a los locales de la siguiente manera:

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

Esto se siente un poco desordenado ya que tanto view_renderer y _partial_renderer son privados, y no hay descriptor de acceso adecuado a la lugareños ivar.

¡Todavía estoy esperando que haya una mejor manera de hacerlo!

0

Pasé alrededor de 4 horas que investigan el código fuente para encontrar una solución, y ahora es parece muy simple:

, añada simplemente "local_assigns" en la que son quieren eval y usarlo.

Por ejemplo:

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

esta cadena será evaluted dentro del contexto del módulo - ActionView::CompiledTemplates y local_assigns serán accesibles allí.