Block level helpers in Ruby on Rails
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.
<div id="container"> <b class="rtop"> <b class="r1"></b> <b class="r2"></b> <b class="r3"></b> <b class="r4"></b> </b> <!--content goes here --> <b class="rbottom"> <b class="r4"></b> <b class="r3"></b> <b class="r2"></b> <b class="r1"></b> </b> </div>
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 = '<div id="container"><b class="rtop"><b class="r1"></b><b class="r2"></b><b class="r3"></b><b class="r4"></b></b><div class="cont">' e = '</div><b class="rbottom"><b class="r4"></b> <b class="r3"></b> <b class="r2"></b> <b class="r1"></b></b></div>' # 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 = '<div id="container"><b class="rtop"><b class="r1"></b><b class="r2"></b><b class="r3"></b><b class="r4"></b></b><div class="cont">' e = '</div><b class="rbottom"><b class="r4"></b> <b class="r3"></b> <b class="r2"></b> <b class="r1"></b></b></div>' # 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)
![]() | Published on April 22nd, 2008 | | 5 Comments | | Posted by Roman Mackovcak |