#40
Jun 04, 2007

Blocks in View

If you try to create a helper method which accepts a block, you will run into a few gotchas. Learn the secrets of blocks in views in this episode.
Tags: views
Download (20.1 MB, 9:06)
alternative download for iPod & Apple TV (11.8 MB, 9:06)
<% side_section do %>
  This is on the side bar.
<% end %>

<% admin_area do %>
  <%= link_to "Edit Task", edit_task_path(@task) %>
<% end %>
# application_helper
def side_section(&block)
  @side_sections ||= []
  @side_sections << capture(&block)
end

def admin_area(&block)
  concat('<div class="admin">', block.binding)
  block.call
  concat("</div>", block.binding)
end

# or...
def admin_area(&block)
  if admin?
    concat content_tag(:div, capture(&block), :class => 'admin'), block.binding
  end
end

RSS Feed for Episode Comments 10 comments

1. chineseGuy Jun 04, 2007 at 01:11

Good example!
I google about "Variable Bindings in Ruby"
http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc
and,with your example,I understand it
tks!


2. Rebort Jun 04, 2007 at 06:10

Wildly useful and solves a small problem I had with my views. Thanks, Ryan!


3. JEG2 Jun 04, 2007 at 06:25

I have just one small suggestion.

When you have Ruby wrap the block into an object for you (by adding a &block parameter), I think it's more consistent to use block.call over yield. Generally I thin you either want to go with a yield/block_given? strategy or a &block/block.call/block.nil? strategy, depending on the method you are writing. But it's probably best not to mix and match. In your examples, we need the block object to get the binding, so the latter is better.


4. Emil Jun 04, 2007 at 08:05

GOOD!!!!!


5. Ryan Bates Jun 04, 2007 at 08:10

@JEG2, thanks for the suggestion. I've seen the mix of yield and &block in other places as well (such as the source of fields_for) which is one reason I didn't think it mattered. But you know Ruby probably better than any of us here, so I'll try to stick with your suggestion. Thanks! :)


6. Jon Buda Jun 04, 2007 at 10:30

Excellent tips, I'll have to implement this soon. One question though...how does the use of blocks in the views work with caching? Does it at all or are there some limitations? Thanks, great screencasts. I look forward to the new ones all the time.


7. Ryan Bates Jun 04, 2007 at 13:47

I don't think there's any issues with caching. You just have to watch out for setting instance variables (like the side sections example). If you cache outside the block, the helper method won't be called every time and the instance variable won't be set.


8. Brian Jul 31, 2007 at 21:43

How do you do something like yield(msg) in actionview?


9. Ryan Bates Jul 31, 2007 at 21:58

@Brian, you should be able to do that without any issues (just like any normal yield call). Is it not working?


10. Brian Jul 31, 2007 at 22:12

Well I mean it does but I want to surround it with tags. ie create div or a ul and then insert the yield(msg) result in it. No point in creating the ul or div if there's nothing to go in it. Do you have the site notify you when comments are posted cause that was ridiculously fast.


11. Ryan Bates Aug 01, 2007 at 07:33

Hmm, not entirely sure what you're asking, but eithe way it should work without any changes. See this pastie code for an example of passing a string to the block.

http://pastie.caboo.se/84044


12. Brian Aug 01, 2007 at 23:08

Sweet. That's exactly what I needed I didn't know you could pass an argument to capture


13. liusong1111 Aug 22, 2007 at 08:21

to weskycn:
Don't say anything not related to the topic. obeying the rule is the most polite than words,okey?
actually,I am a chinese too.
-------
blocks in view is powerful,especially with "capture"'s help.
I finished a "table_for" helper with the mechinism,the usage like this:
<% table_for :users do |t|
     t.column :full_name {|user| h user.first_name + " " + user.last_name}
     t.columns :age,:birthday
     t.columns :$edit,:$show
%>

<% t.erb_column('Destroy') do |user| %>
<% if user.name != 'xxx' %>
  <%= link_to 'Destroy',user_path(user),:method=>:delete %>
<% end %>
<% end
     end
%>

some features like "pagination","odd-even style","column sortable with correct sort-type" supported,and we can imagine more features like "export to excel","Globalization" to be added to "table_for" helper. so only open some options like :sortable=>false,we keep the code clean,consistent and maintainable. (like j2ee's displaytag?)

for it's used in my company,I am sorry not able to share the code to public.

let's enjoy blocks in view :)


14. Clint Moore Nov 25, 2007 at 14:54

Sorry... completely off topic.

If you listen very very closely you can hear frogs in the background. I can't help but imagine that you live on a bijou ala Happy Gilmore or something busting out awesome rails nuggets of smart from your two room shack.


15. space Dec 10, 2007 at 02:17

Is it possible to do something like:

<% my_box do |box| %>
  <% box.head do %>
     ...
  <% end %>
  <% box.content do %>
     ...
  <% end %>
<% end %>

As you see its going to wrap some HTML for a rounded box.

I tried for several hours to find a solution. The main problem is that i cant capture the contents of the block.call(some_function) method. It always outputs everything to the template immediatly.

Is there a way to it?


16. Tobi Jan 26, 2008 at 02:21

Thanks!


17. Georg Ledermann Feb 17, 2008 at 03:31

As in the comment from "space" mentioned, it's a bit complicated to build helper method for multiple wrapped tags. I found, that with HAML this task is very simple, because you get the helper methods "open" and "puts".

I have written a blog entry about this:
http://www.dipl-wirt-inf.de/2008/02/17/elegante-block-helper-mit-haml/

(german language, but you will get point with the code examples).


18. Robert Massaioli Sep 19, 2009 at 20:48

This was a really useful episode, ROR really is awesome in that it lets you write code like that!


19. Yahya Jan 20, 2010 at 16:00

Love your screencasts, learn something new everytime! Thanks


20. Louis Vuitton Speedy 30 M92642 Jul 16, 2010 at 04:58

good


21. asics shose Jul 28, 2010 at 00:12

This was a really useful episode, ROR really is awesome in that it lets you write code like that!


22. free directory list Aug 11, 2010 at 22:18

I think i have same problem too


23. jordan shoes on sale Aug 19, 2010 at 00:19

This was a really useful episode, ROR really is awesome in that it lets you write code like that! Thanks for very good information. Excellent article that will provide the incentive and basis for my works.I wonder if I can mention the article as a bibliographic reference in my work. Thanks!


24. louis vuitton shoes Aug 26, 2010 at 21:10

Thanks for sharing your article. I really enjoyed it. I put a link to my site to here so other people can read it. My readers have about the same interets


25. snow boots Aug 31, 2010 at 01:38

I can't help but imagine that you live on a bijou ala Happy Gilmore or something busting out awesome rails nuggets of smart from your two room shack.


26. louis vuitton sunglasses Sep 01, 2010 at 21:37

Very good post. Made me realize I was totally wrong about this issue. I figure that one learns something new everyday. Mrs Right learned her lesson! Nice, informative website by the way.

Add your comment:

(SKIP THIS ONE)

(required)

(not shown)


(use pastie or gist for code)

sponsored by:
if you want to help:
required:
Get Quicktime Player
Give Back to Open Source