【问题标题】:Using Rails view helpers with Haml::Engine使用带有 Haml::Engine 的 Rails 视图助手
【发布时间】:2011-07-07 12:36:45
【问题描述】:

我有一个 Rails 应用程序,我在其中渲染了一个存储在模型属性中的 Haml 内容块。在那个 Haml 块中使用 Rails 视图助手会很好。目前我在视图助手中使用 Haml::Engine#render 来呈现这个模型属性的内容。它工作得很好,但我不能使用 =link_to 之类的东西。为了说明问题:

irb(main):003:0> haml_text=<<"EOH"
irb(main):004:0" %p
irb(main):005:0"   =image_tag 'someimage'
irb(main):006:0" EOH
=> "%p\n  =image_tag 'someimage'\n"
irb(main):007:0> engine = Haml::Engine.new(haml_text)
=> #<Haml::Engine:0x7fa9ff7f1150 ... >
irb(main):008:0> engine.render
NoMethodError: undefined method `image_tag' for #<Object:0x7fa9ff7e9a40>
        from (haml):2:in `render'
        from /usr/lib/ruby/gems/1.8/gems/haml-3.0.25/lib/haml/engine.rb:178:in `render'
        from /usr/lib/ruby/gems/1.8/gems/haml-3.0.25/lib/haml/engine.rb:178:in `instance_eval'
        from /usr/lib/ruby/gems/1.8/gems/haml-3.0.25/lib/haml/engine.rb:178:in `render'
        from (irb):8

关于如何做到这一点的任何想法?

更好的想法?

【问题讨论】:

    标签: ruby-on-rails haml


    【解决方案1】:

    render 方法允许您指定上下文。类似的东西

    base = Class.new do
      include ActionView::Helpers::AssetTagHelper
      include ApplicationHelper
    end.new
    
    Haml::Engine.new(src).render(base)
    

    可以工作。

    【讨论】:

    • 但是话说回来,很多 Rails 的助手都依赖于控制器/请求。 image_tag 例如将检查主机名(在请求中)。这将非常糟糕地崩溃。
    【解决方案2】:

    Marcel 的方向是正确的。但是您需要从某个地方获得渲染引擎的有效范围。我所做的是用这样的有效范围调用助手:

    在 my_view/edit.html.haml 中

    =my_revertable_field(self, 'hello world')
    

    在 application_helper.rb 中

    def my_revertable_field(haml_scope, title, field)
          template =<<EOS
    .field
      #{label}
      = text_field_tag #{field.name}, #{field.amount}, :size=>5, :class=>"text"
      = image_tag("refreshArrow.gif",:class=>"revert-icon", :style=>"display:none;",:title=>"Revert to default, #{field.default}")
    EOS
    end
    

    那么你有一个有效的haml范围,所以image_tab,form_tag_helpers都可以工作

    【讨论】:

      【解决方案3】:
      class RailsRenderingContext
        def self.create(controller)
          view_context = ApplicationController.helpers
          class << view_context; include Rails.application.routes.url_helpers; end
      
          view_context.request = controller.request
          view_context.view_paths = controller.view_paths
          view_context.controller = controller
      
          view_context
        end
      end
      
      class MyController < ApplicationController
        def show
          # ...
          engine = Haml::Engine.new haml
          ctx = RailsRenderingContext.create(self)
          engine.render ctx 
        end
      end
      

      它对我有用。基于this 问题。

      【讨论】:

      • 优秀的解决方案!如果您只想使用link_to,则可以省略以view_context. 开头的三行,例如一封邮件里面。这样甚至不需要控制器。
      猜你喜欢
      • 2011-09-26
      • 2011-07-11
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 2011-07-16
      • 1970-01-01
      • 1970-01-01
      • 2020-12-20
      相关资源
      最近更新 更多