{"id":289,"date":"2012-08-28T15:32:17","date_gmt":"2012-08-28T15:32:17","guid":{"rendered":"http:\/\/nicholshayes.co.uk\/blog\/?p=289"},"modified":"2013-10-31T15:56:11","modified_gmt":"2013-10-31T15:56:11","slug":"treedecorator","status":"publish","type":"post","link":"http:\/\/nicholshayes.co.uk\/blog\/?p=289","title":{"rendered":"TreeDecorator"},"content":{"rendered":"<p>On a couple of my projects, I&#8217;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&#8217;ve used <a href=\"http:\/\/developer.yahoo.com\/yui\/treeview\/\">YUI 2 TreeView<\/a> in the past, and this time I wanted to use <a href=\"http:\/\/wwwendt.de\/tech\/dynatree\/index.html\">Dynatree<\/a>. <\/p>\n<p>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.<\/p>\n<p>So to prevent me having to reinvent the conversion of a nested set into a nested unordered list, I&#8217;ve created <a href=\"https:\/\/github.com\/reggieb\/TreeDecorator\">TreeDecorator<\/a>. It is installed into a rails app with:<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\">gem <span class=\"st0\">'tree_decorator'<\/span><\/div><\/div>\n<p>With that in place I could create this helper method (My nested set object is Event):<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\">&nbsp; <span class=\"kw1\">def<\/span> events_in_unorder_list<span class=\"br0\">&#40;<\/span>events<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; hanger = <span class=\"re2\">TreeDecorator::ObjectHanger<\/span>.<span class=\"me1\">new<\/span><span class=\"br0\">&#40;<\/span>events<span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; hanger.<span class=\"me1\">outer<\/span> <span class=\"br0\">&#123;<\/span><span class=\"sy0\">|<\/span>content<span class=\"sy0\">|<\/span> content_tag<span class=\"br0\">&#40;<\/span><span class=\"st0\">'ul'<\/span>, content.<span class=\"me1\">html_safe<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; hanger.<span class=\"me1\">inner<\/span> <span class=\"br0\">&#123;<\/span><span class=\"sy0\">|<\/span>content<span class=\"sy0\">|<\/span> content_tag<span class=\"br0\">&#40;<\/span><span class=\"st0\">'li'<\/span>, content.<span class=\"me1\">html_safe<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; hanger.<span class=\"me1\">element<\/span> <span class=\"br0\">&#123;<\/span><span class=\"sy0\">|<\/span>event<span class=\"sy0\">|<\/span> link_to<span class=\"br0\">&#40;<\/span>event.<span class=\"me1\">title<\/span>.<span class=\"me1\">html_safe<\/span>, event_path<span class=\"br0\">&#40;<\/span>event<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; hanger.<span class=\"me1\">tree<\/span><br \/>\n&nbsp; <span class=\"kw1\">end<\/span><\/div><\/div>\n<p>That then gives me my nested ordered list, and it is then trivial to make it dynamic:<\/p>\n<div class=\"codecolorer-container ruby default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"ruby codecolorer\"><span class=\"sy0\">&lt;<\/span>div <span class=\"kw1\">class<\/span>=<span class=\"st0\">&quot;events&quot;<\/span><span class=\"sy0\">&gt;<\/span><br \/>\n<span class=\"sy0\">&lt;%<\/span>= events_in_unorder_list<span class=\"br0\">&#40;<\/span>@event_roots<span class=\"br0\">&#41;<\/span> <span class=\"sy0\">%&gt;<\/span><br \/>\n<span class=\"sy0\">&lt;\/<\/span>div<span class=\"sy0\">&gt;<\/span><br \/>\n<br \/>\n<span class=\"sy0\">&lt;%<\/span>= javascript_tag<span class=\"br0\">&#40;<\/span><span class=\"st0\">'$(&quot;.events&quot;).dynatree({});'<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">%&gt;<\/span><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>On a couple of my projects, I&#8217;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 &hellip; <a href=\"http:\/\/nicholshayes.co.uk\/blog\/?p=289\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/289"}],"collection":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=289"}],"version-history":[{"count":10,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/289\/revisions"}],"predecessor-version":[{"id":465,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/289\/revisions\/465"}],"wp:attachment":[{"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=289"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/nicholshayes.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}