Web developer often comes to a situation where he needs to “decorate” a block of a page. There is a simple solution and simple and elegant solution.
Helpers concept in Ruby on Rails is very powerful and will be used to do the trick.
Imagine, you want to create a rounded box helper similar to Nifty Corners (http://www.html.it/articoli/nifty/index.html), but you do not want to use javascript. So, a handy helper needs to be created.
The principle of the Nifty Corners trick is adding few b tags before content, few b tags after it and few lines to CSS.
and modification of CSS
.rtop, .rbottom{display:block}
.rtop *, .rbottom *{display: block; height: 1px; overflow: hidden}
.r1{margin: 0 5px;}
.r2{margin: 0 3px;}
.r3{margin: 0 2px;}
.r4{margin: 0 1px; height: 2px;}
.r1, .r2, .r3, .r4 {background-color:red;}
.cont{background-color:red;}
Easy solution
The easy solution uses two helpers. One to put before the content and one to put it after. So, the view could look like:
...
<%= round_box_start %>
content
<%= round_box_end %>
...
Well, it does not look good. So, what about the other solution?
Easy and elegant solution
We will create a block level helper. The view will look much better.
...
<% round_box do %>
content
<% end %>
...
Now, let’s create the helper:
def round_box(&block)
b = ''
e = ' '
# Get the data from the block
data = capture(&block)
res = b + data + e
# Use concat method to pass text back to the view
concat(res, block.binding)
end
Good, but works only for red boxes. How to pass another color? Simply:
...
<% round_box(color) do %>
content
<% end %>
...
and in helper
def round_box(color, &block)
b = ''
e = ' '
# Get the data from the block
data = capture(&block)
res = b + data + e
# Use concat method to pass text back to the view
concat(res, block.binding)
end
Final implementation of the colored box is left as a homework :o)
Thanks for posting this. Blocks in helpers is something many people struggle with.
An alternative to this is to render a partial as a layout. This way you don’t have to put the HTML in ruby strings. See this: http://pastie.caboo.se/188186
I haven’t tried it, but you could probably pass a :locals hash to specify the color.
Thanks for posting this. Great advice.
@Ryan Bates – I was trying something similar to what you put up on pastie, and locals work just fine. There is the advantage you mentioned in that you don’t have to put HTML code as Ruby Strings.
render :layout => ‘shared/sidebar’, :locals => { :links => side_links }
[From The example i was working on]
Guys, thanks for your comments. You are right. My example was not perfect. Nevertheless, you made it a valuable post with your additions.
Or, you can just use Better Partials:
http://www.railsjedi.com/posts/22-Better-Partials-Plugin-for-Ruby-on-Rails