lib/simple_navigation/item_container.rb in simple-navigation-1.4.2 vs lib/simple_navigation/item_container.rb in simple-navigation-2.0.0

- old
+ new

@@ -1,16 +1,18 @@ module SimpleNavigation - # Holds the Items for a navigation 'level' (either the primary_navigation or a sub_navigation). + # Holds the Items for a navigation 'level'. class ItemContainer - attr_reader :items - attr_accessor :renderer, :dom_id, :dom_class + attr_reader :items, :level + attr_accessor :renderer, :dom_id, :dom_class, :auto_highlight - def initialize #:nodoc: + def initialize(level=1) #:nodoc: + @level = level @items = [] - @renderer = Configuration.instance.renderer + @renderer = SimpleNavigation.config.renderer + @auto_highlight = true end # Creates a new navigation item. # # The <tt>key</tt> is a symbol which uniquely defines your navigation item in the scope of the primary_navigation or the sub_navigation. @@ -28,27 +30,76 @@ # be rendered (e.g. <tt>:unless => Proc.new { current_user.admin? }</tt>). The # proc should evaluate to a true or false value and is evaluated in the context of the view. # # The <tt>block</tt> - if specified - will hold the item's sub_navigation. def item(key, name, url, options={}, &block) - (@items << Item.new(key, name, url, options, block)) if should_add_item?(options) + (@items << SimpleNavigation::Item.new(self, key, name, url, options, block)) if should_add_item?(options) end # Returns the Item with the specified key, nil otherwise. + # def [](navi_key) items.find {|i| i.key == navi_key} end + + # Returns the level of the item specified by navi_key. + # Recursively works its way down the item's sub_navigations if the desired item is not found directly in this container's items. + # Returns nil item cannot be found. + # + def level_for_item(navi_key) + my_item = self[navi_key] + return self.level if my_item + items.each do |i| + if i.sub_navigation + level = i.sub_navigation.level_for_item(navi_key) + return level unless level.nil? + end + end + return nil + end # Renders the items in this ItemContainer using the configured renderer. # - # Set <tt>include_sub_navigation</tt> to true if you want to nest the sub_navigation into the active primary_navigation - def render(current_navigation, include_sub_navigation=false, current_sub_navigation=nil) - self.renderer.new(current_navigation, current_sub_navigation).render(self, include_sub_navigation) + # Set <tt>include_sub_navigation</tt> to true if you want to nest the sub_navigation into the active parent_navigation + def render(include_sub_navigation=false) + self.renderer.new.render(self, include_sub_navigation) end + # Returns true if any of this container's items is selected. + # + def selected? + items.any? {|i| i.selected?} + end + + # Returns the currently selected item, nil if no item is selected. + # + def selected_item + self[current_explicit_navigation] || items.find {|i| i.selected?} + end + + # Returns the current navigation that has been explicitely defined in the controller for this container's level. + # Returns nil if no explicit current navigation has been set. + # + def current_explicit_navigation + SimpleNavigation.current_navigation_for(level) + end + + # Returns the active item_container for the specified level + # (recursively looks up items in selected sub_navigation if level is deeper than this container's level). + # + def active_item_container_for(desired_level) + return self if self.level == desired_level + return nil unless selected_sub_navigation? + return selected_item.sub_navigation.active_item_container_for(desired_level) + end + private + def selected_sub_navigation? + !!(selected_item && selected_item.sub_navigation) + end + # partially borrowed from ActionSupport::Callbacks def should_add_item?(options) #:nodoc: [options.delete(:if)].flatten.compact.all? { |m| evaluate_method(m) } && ![options.delete(:unless)].flatten.compact.any? { |m| evaluate_method(m) } end @@ -60,10 +111,9 @@ method.call else raise ArgumentError, ":if or :unless must be procs or lambdas" end end - end end \ No newline at end of file