Shrinking our view code
View, helper is a good way to modulise your view code.
We found these two functions from dzone for our acts_as_tree categories.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
def display_categories(categories, open_cat = nil, &block) html = Builder::XmlMarkup.new html.ul(:id => "category-tree", :class => "tree") do categories.each do |c| if c.parent_id == 0 li = "<li class="liOpen">" li += if block_given? yield(c) else link_to c.name, admin_edit_category_path(c) # :class => "#{'active' if c.id == open_cat}" end li += find_all_subcategories(c, open_cat, &block) if c.children.size > 0 li += "</li>" html << li end end end end def find_all_subcategories(category, open_cat = nil, &block) if category.children.size > 0 ret = '<ul>' category.children.each { |c| li = "<li class="liOpen">" li += if block_given? yield(c) else link_to c.name, admin_edit_category_path(c) ,:class => "#{'selected' if c.id == open_cat }" end li += find_all_subcategories(c, &block) li += "</li>" ret += li } ret += '</ul>' else '' end end |
Thanks to Ben from #ror_au irc chatroom today, I was able to cut that helper into 15 lines with added features.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
def display_categories(categories, open_cat = nil, &block) open_cat_ancestors = Category.find(open_cat).ancestors if open_cat content_tag(:ul, categories.inject("") do |list_items, c| list_items + content_tag(:li, (if block_given? yield(c,open_cat) else link_to c.name, admin_edit_category_path(c) end) + (c.children.any? ? display_categories(c.children, open_cat, &block) : "") , :class=>"#{'liOpen' if open_cat_ancestors && open_cat_ancestors.include?(c) }" ) end, :id => "category-tree", :class => "tree" ) end |
To use it just call it by
1 |
<%= display_categories(Category.find_level1, params[:category_id]) %>
|
Or you can customise theblock by
1 2 3 |
display_categories(Category.find_level1, params[:category_id]) do |cat, open_cat|
link_to h(cat.name), admin_products_path(:category_id => cat),:class => "#{'selected' if cat.id == open_cat.to_i }"
end
|
