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

不使用Rails/JS,仅通过Ruby/ERB捕获复用HTML代码块的方法

原生Ruby/ERB实现HTML代码块重复调用的方案

完全可以仅用原生Ruby/ERB实现类似Rails的content_for功能,不需要依赖Rails框架,实现方式和你在Rails中的使用习惯几乎一致。

实现原理

只需要在ERB的渲染上下文中维护一个存储命名内容块的哈希,封装两类逻辑即可:

  • 调用时传入代码块:捕获块内的ERB渲染结果,存入对应命名的哈希槽位
  • 调用时不传代码块:直接返回对应命名槽位已存储的内容

完整实现示例

第一步:编写核心逻辑代码

require 'erb'

# 定义ERB渲染上下文类,存储内容块和实现content_for方法
class ERBContext
  def initialize
    @content_blocks = {}
  end

  def content_for(name, &block)
    if block_given?
      # 捕获块内的渲染结果存入哈希
      @content_blocks[name.to_s] = block.call
    else
      # 直接返回已存储的内容
      @content_blocks[name.to_s]
    end
  end

  # 暴露binding供ERB渲染调用
  def get_binding
    binding
  end
end

第二步:编写ERB模板

你可以把下面内容存为template.erb,用法和你在Rails中的写法完全一致:

<% content_for :mycontent do %>
  <div class="reusable-block">
    some html code
    that I want to capture
    etc
  </div>
<% end %>

<!-- 第一次复用代码块 -->
<%= content_for :mycontent %>

<!-- 第二次复用代码块 -->
<p>下面是第二次调用的内容:</p>
<%= content_for :mycontent %>

第三步:渲染ERB模板

# 初始化上下文
context = ERBContext.new
# 读取模板文件
template = File.read('template.erb')
# 渲染ERB
renderer = ERB.new(template)
result = renderer.result(context.get_binding)
# 输出最终渲染结果
puts result

进阶优化(可选)

如果需要支持追加内容而不是覆盖原有内容,可以修改content_for方法:

def content_for(name, append: false, &block)
  name = name.to_s
  if block_given?
    content = block.call
    if append && @content_blocks[name]
      @content_blocks[name] += content
    else
      @content_blocks[name] = content
    end
  else
    @content_blocks[name]
  end
end

调用时添加append: true参数即可实现内容追加:

<% content_for :mycontent, append: true do %>
  <p>追加的额外内容</p>
<% end %>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:24:09