2016-08-05 8 views
0

ここでは何か変わったことがありますが、平凡なRubyを使用してERBに複数のcontent_forブロックを実装しようとすると理解できません。ここでERC内のProc

は私のコードです:

# helper.rb 
require 'erb' 

def render(path) 
    ERB.new(File.read(path)).result(binding) 
end 

def content_for(key, &block) 
    content_blocks[key.to_sym] = block 
end 

def yield_content(key) 
    content_blocks[key.to_sym].call 
end 

def content_blocks 
    @content_blocks ||= Hash.new 
end 

、テンプレート:私はテストするIRBを開くとyield_content :script\n\n\nプリペンドを持って、なぜ、なぜ

<% #test.html.erb %> 
<% content_for :style do %> 
    style 
<% end %> 
<% content_for :body do %> 
    body 
<% end %> 
<% content_for :script do %> 
    script 
<% end %> 

、私は

irb(main):001:0> require './helper' 
=> true 
irb(main):002:0> render 'test.html.erb' 
=> "\n\n\n" 
irb(main):003:0> content_blocks 
=> {:style=>#<Proc:[email protected](erb):2>, :body=>#<Proc:[email protected](erb):5>, :script=>#<Proc:[email protected](erb):8>} 
irb(main):004:0> yield_content :script 
=> "\n\n\n\n script\n" 
irb(main):005:0> yield_content :style 
=> "\n\n\n\n script\n\n style\n" 

を取得しますyield_content :styleにはscript\n\nが見つかりました。

答えて

2

あなたは

ERB.new(File.read(path)).src 

を行う場合、あなたはあなたのテンプレートをコンパイルするものERB見ることができます。テンプレートは

_erboutは、テンプレートからの出力を蓄積するバッファである
_erbout = '' 
_erbout.concat "\n" 
#test.html.erb 
_erbout.concat "\n" 
content_for :style do 
    _erbout.concat "\n style\n" 
end 

(読みやすくするためにフォーマットされた)ように見える終わります。 _erboutはちょうどローカル変数です。

procsを呼び出すと、それらはすべてテンプレートのレンダリングの結果を含む同じバッファに追加されます。

+0

ご回答ありがとうございます。どうすれば 'yield_content:script'が' script'だけを出力するのですか? – Canh

+0

わかりません。 Railsの実装からインスピレーションを得るかもしれない。 –

+0

私は検索をしてからやりました。 'render'関数を' ERB.new(File.read(path)、nil、nil、 "@outbuf")。result(binding) 'に変更することによって、ERBはバッファを' _erbout'の代わりに他の変数に格納します。次に、 'yield_content'関数で、Procを呼び出す前に@outbufをクリアして終了します。私は正しい方向へ向いてくれてありがとうございました。 – Canh