Обработчики шаблонов Rails 3.1

У меня есть ruby ​​gem, poirot, который позволяет использовать шаблоны усов в Rails. Обработчик шаблонов, который у меня есть, расширялся от ActionView::Template::Handler, однако в Rails 3.1 это кажется устаревшим.

Я реорганизовал обработчик, чтобы он соответствовал предупреждениям об устаревании. При этом я теперь не могу передать локальные жители или контекст представления шаблону. Я не могу понять, как заставить это работать с 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

В приведенном выше коде для обработчика я получаю шаблон, который является экземпляром ActionView::Template. Но я не уверен, как получить контекст представления, который должен включать местных жителей и т.д.

Может ли кто-нибудь указать мне в правильном направлении?


person Oliver Nightingale    schedule 11.08.2011    source источник


Ответы (2)


Хорошо, у меня есть решение, я не уверен, что оно лучшее, мне оно кажется немного хакерским!

В моем классе просмотра мне удалось получить доступ к локальным жителям, выполнив следующие действия:

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

Это кажется немного запутанным, так как и view_renderer, и _partial_renderer являются приватными, и нет надлежащего доступа к локальным переменным ivar.

Я все еще надеюсь, что есть лучший способ сделать это!

person Oliver Nightingale    schedule 12.08.2011

Я потратил около 4 часов на изучение исходного кода, чтобы найти решение, и теперь оно кажется очень простым:

просто добавьте «local_assigns», где вы хотите его оценить и использовать.

Например:

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

эта строка будет оцениваться внутри контекста модуля - там будут доступны ActionView::CompiledTemplates и local_assigns.

person BitOfUniverse    schedule 09.01.2012