module Cms module MenuHelper # This will render a menu based on the page # With no options passed, it will render a menu that shows all the child sections of the root # and then it will show the path of decendent sections all the way to the current page. # The resulting HTML is a DIV with a UL in it. Each LI will have an A in it. If the item is a Section, # the HREF of the A will be the URL of the first non-archived page that is a direct child of that Section. # Hidden pages will not show up, but if the first page in a Section is hidden, it will be used as the URL # for that Section. This is commonly done to have a page for a Section and avoid having duplicates in the # navigation. # # You can change the behavior with the following options, all of these are optional: # # ==== Options # * :page - What page should be used as the current page. If this value is omitted, the value in @page will be used. # * :path - This will be used to look up a section and that section will used to generate the menu. The current page will # still be the value of the page option or @page. Note that this is the path to a section, not a path to a page. # * :from_top - How many below levels from the root the tree should start at. # All sections at this level will be shown. The default is 0, which means show all # section that are direct children of the root # * :depth - How many levels deep should the tree go, relative to from_top. # If no value is supplied, the tree will go all the way down to the current page. # If a value is supplied, the tree will be that many levels underneath from_top deep. # * :limit - Limits the number of top-level elements that will be included in the list # * :class - The CSS Class that will be applied to the div. The default value is "menu". # * :show_all_siblings - Passing true for this option will make all sibilings appear in the tree. # the default is false, in which case only the siblings of nodes within the open path will appear. # # ==== Examples # # Assume you have the structure the NFL, which is NFL > Conference > Division > Team, # with teams being a Page, everything else a Section. Also, assume we are on the # Baltimore Ravens page. If you're not a footbal fan, see http://sports.yahoo.com/nfl/teams # # render_menu # # => # # render_menu(:depth => 2, :show_all_siblings => true) # # => def render_menu(options={}) #Intialize parameters page = options[:page] || @page return nil unless page # Path to the section if options.has_key?(:path) section_for_path = Section.find_by_path(options[:path]) raise "Could not find section for path '#{options[:path]}'" unless section_for_path ancestors = section_for_path.ancestors(:include_self => true) else ancestors = page.ancestors end from_top = options.has_key?(:from_top) ? options[:from_top].to_i : 0 depth = options.has_key?(:depth) ? options[:depth].to_i : 1.0/0 id = options[:id] || "menu" css_class = options[:class] || "menu" show_all_siblings = !!(options[:show_all_siblings]) limit = options[:limit] html = "
\n" if from_top > ancestors.size return html << "
\n" else ancestors = ancestors[from_top..-1] end #We are defining a recursive lambda that takes the top-level sections #d is the current depth fn = lambda do |nodes, d| indent = (d-1)*4 html << "\n".indent(indent+2) end fn.call(ancestors.first.visible_child_nodes(:limit => limit), 1) unless ancestors.first.blank? html << "\n" end end end