ERB内部程序



当我尝试使用普通Ruby在ERB中实现多个content_for块时,这里发生了一些奇怪的事情,我无法理解。

这是我的代码:

# 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

和模板:

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

当我打开irb进行测试时,我会得到

irb(main):001:0> require './helper'
=> true
irb(main):002:0> render 'test.html.erb'
=> "nnn"
irb(main):003:0> content_blocks
=> {:style=>#<Proc:0x005645a6de2b18@(erb):2>, :body=>#<Proc:0x005645a6de2aa0@(erb):5>, :script=>#<Proc:0x005645a6de2a28@(erb):8>}
irb(main):004:0> yield_content :script
=> "nnnn  scriptn"
irb(main):005:0> yield_content :style
=> "nnnn  scriptnn  stylen"

为什么yield_content :script得到了nnn,为什么yield_content :style得到了结果中的scriptnn

如果进行

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

然后你可以看到erb把你的模板编译成什么

_erbout = ''
_erbout.concat "n"
#test.html.erb
_erbout.concat "n"
content_for :style do
  _erbout.concat "n  stylen"
end

其中_erbout是累积模板输出的缓冲区。_erbout只是一个局部变量,m

当你调用proc时,它们都只是附加到同一个缓冲区,这个缓冲区已经包含了模板渲染的结果。

相关内容

最新更新