We’re going to make a quick little helper to generate little “tip” sidebar items with optional headers. Here’s the type of API we want:
<% tip "Block Helpers Help!" do %> <p>They really do!</p> <p>Use them, or deprecate yourself immediately.</p> <% end %>
Notice the first line is in an ERB evaluation block, meaning we’re not trying to insert its result into the template—since we’re not even finished passing all the arguments to it, after all; the block.
And here’s how to make it all happen:
def tip(name=nil,&block)
concat("<div class='tip'>", block.binding)
concat(content_tag('h3',name), block.binding) if name
yield # now insert the markup in the block
concat('</div>', block.binding)
end
So, what’s this block.binding tomfoolery?
To add anything to the page, we need to use concat, and ERB needs to know where add our text—the context. Handily, our block lives out in the template, and its binding is exactly what we need.
And that’s about it. It’s really not very complex, provided you have at least a little bit of Ruby experience, know what a block is, and can deal with ERB’s foibles.
So use block helpers!
Reference: form_helper.rb (in Rails) has some fairly decent examples. Rails Recipes, a great book by Chad Fowler also has a recipe on the subject. Buy it—you’re a smart Rails developer, right?
Helpers that take blocks are a core element of the new approach to developing views for Rails. What are they, and why should they be used? To put it plainly, block helpers are a bit of Ruby magic that will save you time and no little amount of sanity.
Let’s use a simple example. Imagine a situation where you are wrapping chunks of markups in a div with the same CSS class. This is happening in various templates.
The old approach would either be to just type in the wrapping div manually every time, or maybe have two partials; one rendered before, and the other after the chunk of markup.
This is the type of “insert header here,” and “insert footer here” PHP-like clunkiness I try to avoid.
Block helpers make this inelegant kludge unnecessary. They allow you insert “common” markup before and after the block, and also to yield whatever object you’d like to the block so it can be used—like form_for’s builders.
Here’s a diagram, just for the hell of it.

Now, let’s continue by giving a simple example.