TreeDecorator

On a couple of my projects, I’ve wanted a dynamic tree representation of a group of objects. acts_as_nested_set and it variants (such as awesome_nested_set) work well for creating the back-end structure. There are plenty of JavaScript libraries that will help you create a dynamic tree. I’ve used YUI 2 TreeView in the past, and this time I wanted to use Dynatree.

What I find takes time is pulling the two together. Specifically, I like to output the items in an unordered list and then used the JavaScript library to rebuild the list as a dynamic tree. That way the list degrades nicely if there is a JavaScript issue. However, getting an acts_as_nested_set group into an nested ordered list is tiresome.

So to prevent me having to reinvent the conversion of a nested set into a nested unordered list, I’ve created TreeDecorator. It is installed into a rails app with:

gem 'tree_decorator'

With that in place I could create this helper method (My nested set object is Event):

  def events_in_unorder_list(events)
    hanger = TreeDecorator::ObjectHanger.new(events)
   
    hanger.outer {|content| content_tag('ul', content.html_safe)}
    hanger.inner {|content| content_tag('li', content.html_safe)}
    hanger.element {|event| link_to(event.title.html_safe, event_path(event))}
   
    hanger.tree
  end

That then gives me my nested ordered list, and it is then trivial to make it dynamic:

<div class="events">
<%= events_in_unorder_list(@event_roots) %>
</div>

<%= javascript_tag('$(".events").dynatree({});') %>
This entry was posted in Ruby. Bookmark the permalink.