You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ERB在.yml.erb中嵌入子模板时内容丢失问题求助

问题原因与解决方案

错误根源

你当前的写法中,子模板的ERB实例默认会直接将渲染内容输出到$stdout,而父模板里的<%=试图接收返回值再输出,这会导致输出顺序彻底混乱——子模板的内容会先于父模板的前置内容被打印,缓冲区的处理逻辑会直接覆盖掉父模板嵌入代码上方的内容,哪怕去掉gsub处理,这个核心冲突依然存在。

修复方案

方案一:复用父模板的输出缓冲区(推荐)

修改父模板中的嵌入代码,指定子模板ERB使用父模板的输出缓冲区,避免直接输出到标准输出:

<% ERB.new(File.read('child.yml.erb'), nil, ' ', '@output_buffer').result(binding) %>
  • 第四个参数'@output_buffer':让子模板的渲染内容直接写入父模板正在使用的输出缓冲区,确保内容嵌入位置正确,不会打乱整体输出顺序。
  • 缩进处理:如果需要给子模板内容添加8空格缩进,保留你的gsub逻辑即可:
    <% ERB.new(File.read('child.yml.erb').gsub(/^/, ' ' * 8), nil, ' ', '@output_buffer').result(binding) %>
    

方案二:捕获子模板输出为字符串(纯Ruby环境适用)

如果你的环境不支持@output_buffer(非Rails等框架场景),可以用StringIO手动捕获子模板的输出,再输出到父模板:

<%= begin
  output = StringIO.new
  original_stdout = $stdout
  $stdout = output
  ERB.new(File.read('child.yml.erb')).result(binding)
  $stdout = original_stdout
  output.string.gsub(/^/, ' ' * 8)
end %>

验证示例

假设父模板parent.yml.erb内容:

env_a:
  key1: value1
<% # 嵌入子模板 %>
<% ERB.new(File.read('child.yml.erb').gsub(/^/, ' ' * 8), nil, ' ', '@output_buffer').result(binding) %>
env_d:
  key4: value4

子模板child.yml.erb内容:

env_b:
  key2: value2
env_c:
  key3: value3

渲染后会得到正确的嵌套结果:

env_a:
  key1: value1
        env_b:
          key2: value2
        env_c:
          key3: value3
env_d:
  key4: value4

内容的提问来源于stack exchange,提问作者Andrew Lim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 10:23:30