Rails has had to use some tricks in order to get block helpers to work as wanted, and they changed moving from Rails 2 to Rails 3 (see the blogposts Simplifying Rails Block Helpers and Block Helpers in Rails 3 for more info).
The form_for
helper in Rails 2.3 works by directly writing to the output buffer from the method, using the Rails concat
method. In order to do something similar in Sinatra, you’ll need to find a way of writing to the output from your helper in the same way.
Erb works by creating Ruby code that builds up the output in a variable. It also allows you to set the name of this variable, by default it is _erbout
(or _buf
in Erubis). If you change this to be an instance variable rather than a local variable (i.e. provide a variable name that starts with @
) you can access it from helpers. (Rails uses the name @output_buffer
).
Sinatra uses Tilt for rendering templates, and Tilt provides an :outvar
option for setting the variable name in Erb or Erubis templates.
Here’s an example of how this would work:
# 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
With this (fairly simple) example, an Erb template like this:
<% form_helper do %>
... call other methods here
<% end %>
results in the generated HTML:
<form>
... call other methods here
</form>