问题描述
(注意:我使用的是 Ruby 的 erb
,而不是 Rails。)
当使用当前绑定从另一个 ERB 模板中解析一个 ERB 模板时,在调用内部模板之前的外部模板的文本会丢失。
例如:
inner
outer
<%= ERB.new(File.read('inner.erb')).result(binding) %>
outer
测试脚本erb-test
(必须做chmod +x erb-test
):
#!/usr/bin/env ruby
require 'erb'
puts ERB.new(File.read('outer.erb')).result
./erb-test
的输出是:
inner
outer
如图所示,outer.erb
模板文件中指定的第一个“外部”字符串丢失。
如果我们从 binding
中的 ERB 调用中删除 outer.erb
:
<%= ERB.new(File.read('inner.erb')).result %>
...然后我们现在看到外部模板中指定的第一个 outer
:
outer
inner
outer
这是一个错误吗?你建议如何解决这个问题?我意识到最好限制模板可用的状态,通常我使用 ERB#result_with_hash
来做到这一点,但在子模板的情况下,即从另一个模板调用的模板,对我来说似乎合理内部模板继承了外部模板的绑定,因为它已经被限制了。
解决方法
这可以通过使用 eoutvar
parameter to ERB.new
来解决,如下所示:
<%= ERB.new(File.read('inner.erb'),eoutvar: '@inner').result(binding) %>
ERB 源代码中的注释进一步解释了它:
# _eoutvar_ can be used to set the name of the variable ERB will build up
# its output in. This is useful when you need to run multiple ERB
# templates through the same binding and/or when you want to control where
# output ends up. Pass the name of the variable to be used inside a String.
将outer.erb
的内容改为:
outer
<%= ERB.new(File.read('inner.erb'),eoutvar: '@inner').result(binding) %>
outer
...结果是:
outer
inner
outer
请注意,如果您在构造函数调用中传递未命名参数,则需要改用命名方法,例如对于修剪模式:
ERB.new(File.read(erb_filespec),eoutvar: eoutvar,trim_mode: '-')
代替:
template = ERB.new(File.read(erb_filespec),'-')