Rorcraft Blog

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 =&gt; "#{'active' if c.id == open_cat}"
        end
        li += find_all_subcategories(c, open_cat, &amp;block) if c.children.size &gt; 0
        li += "</li>"
        html &lt;&lt; li

      end
    end
  end
end

def find_all_subcategories(category, open_cat = nil, &amp;block)
  if category.children.size &gt; 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 =&gt; "#{'selected' if c.id == open_cat }"
      end
      li += find_all_subcategories(c, &amp;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, &amp;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, &amp;block)  : "") ,
         :class=&gt;"#{'liOpen' if open_cat_ancestors &amp;&amp; open_cat_ancestors.include?(c) }"
       )
     end,
    :id =&gt; "category-tree", :class =&gt; "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
blog comments powered by Disqus

Contact

We love to hear about your web projects.
Email:
Sydney: +61 421 591 943
Hong Kong:+852 6901 2682

Categories