module ExpressTemplates module Components # # Create an html table or ol (ordered list) for # a model object representing a tree of similar objects. # # The objects must respond to :children. # # The block is passed a NodeBuilder which may accept field names. # # Example: # # ```ruby # tree_for(:roles) do |role| # role.name # end # ``` # # If the view has an @roles variable with a Role having children, # this will turn into markup such as the following: # # # class TreeFor < Container def node_renderer return (-> (node, renderer) { ExpressTemplates::Indenter.for(:tree) do |ws, wsnl| "#{wsnl}
  • "+ _yield + if node.children.any? ExpressTemplates::Indenter.for(:tree) do |ws, wsnl| "#{wsnl}" end + "#{wsnl}
  • " else "" end end }).source.sub(/\W_yield\W/, compile_children.lstrip) end def compile collection = _variablize(@options[:id]) member = @options[:id].to_s.singularize return 'ExpressTemplates::Components::TreeFor.render_in(self) { node_renderer = '+node_renderer.gsub(/node/, member)+' ExpressTemplates::Indenter.for(:tree) do |ws, wsnl| "#{ws}\n" end }' end private def _variablize(sym) "@#{sym}" end end end end