【问题标题】:How to implement form_tag helpers without actionview?如何在没有 actionview 的情况下实现 form_tag 助手?
【发布时间】:2023-12-18 22:18:02
【问题描述】:

我正在开发一个 Sinatra 应用程序,并想编写自己的表单助手。在我的 erb 文件中,我想使用 rails 2.3 样式语法并将块传递给 form_helper 方法:

<% form_helper 'action' do |f| %>  
  <%= f.label 'name' %>  
  <%= f.field 'name' %>  
  <%= f.button 'name' %>  
<% end %>    

然后在我的简化表单助手中,我可以创建一个 FormBuilder 类并将方法生成到 erb 块,如下所示:

module ViewHelpers  
  class FormBuilder  
    def label(name)
      name  
    end  
    def field(name)
      name  
    end  
    def button(name)
      name  
    end  
  end  
  def form_helper(action) 
    form = FormBuilder.new 
    yield(form)  
  end  
end    

我不明白的是如何输出周围的&lt;form&gt;&lt;/form&gt;标签。有没有办法只在第一个和最后一个 &lt;%= f.___ %&gt; 标签上附加文本?

【问题讨论】:

  • 我建议使用Padrino's form helpers and/or builders 而不是自己滚动。 gem 可作为独立插件使用,可与任何 Ruby 框架一起使用。
  • Padrino,或者使用它的一部分是一个非常好的建议,我可能会走这条路。我主要是想确保我了解事情是如何结合在一起的。

标签: ruby sinatra block erb view-helpers


【解决方案1】:

Rails 不得不使用一些技巧来让块助手按需要工作,并且他们从 Rails 2 迁移到 Rails 3(有关更多信息,请参阅博文 Simplifying Rails Block HelpersBlock Helpers in Rails 3)。

Rails 2.3 中的form_for 助手由directly writing to the output buffer from the method 工作,使用Rails 的concat 方法。为了在 Sinatra 中执行类似的操作,您需要找到一种以相同方式写入帮助程序输出的方法。

Erb 通过创建在变量中构建输出的 Ruby 代码来工作。它还允许您设置此变量的名称,默认为_erbout(或Erubis 中的_buf)。如果您将其更改为实例变量而不是局部变量(即提供以 @ 开头的变量名),您可以从帮助程序访问它。 (Rails 使用名称@output_buffer)。

Sinatra 使用Tilt 渲染模板,Tilt 提供:outvar 选项用于设置 Erb 或 Erubis 模板中的变量名称。

这是一个如何工作的示例:

# set the name of the output variable
set :erb, :outvar => '@output_buffer'

helpers do
  def form_helper
    # use the new name to write directly to the output buffer
    @output_buffer << "<form>\n"

    # yield to the block (this is a simplified example, you'll want
    # to yield your FormBuilder object here)
    yield

    # after the block has returned, write any closing text
    @output_buffer << "</form>\n"
  end
end

通过这个(相当简单的)示例,一个像这样的 Erb 模板:

<% form_helper do %>
  ... call other methods here
<% end %>

生成的 HTML:

<form>
  ... call other methods here
</form>

【讨论】:

  • 感谢您的回答 - 将 :outvar 设置为实例变量并写入它是缺少的拼图。我将不得不花一些时间深入研究 Tilt 和 Erb,但这让我开始并运行。
最近更新 更多