2011-03-02 72 views
7

我有一個Rails應用程序,其中我正在渲染模塊屬性中存儲的Haml塊的塊。在那個Haml塊中使用Rails視圖助手會很好。目前,我在視圖助手中使用Haml :: Engine#渲染來呈現此模型屬性的內容。它工作得不錯,但我不能使用= link_to之類的東西。爲了說明問題:使用Rails視圖助手與Haml ::引擎

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 

任何想法如何做到這一點?

更好的主意?

回答

14

render方法允許您指定上下文。類似於

base = Class.new do 
    include ActionView::Helpers::AssetTagHelper 
    include ApplicationHelper 
end.new 

Haml::Engine.new(src).render(base) 

可以工作。

+2

但是再次,很多Rails的幫手依賴於控制器/請求。例如'image_tag'將檢查主機名(在請求中)。這會非常糟糕地崩潰。 – 2011-03-02 19:16:23

3

馬塞爾正朝着正確的方向前進。但是你需要從某處獲取渲染引擎的有效範圍。我所做的是叫幫手,像這樣一個有效的範圍:

在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所有工作

0
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問題。