lib/active_admin/menu_item.rb
module ActiveAdmin class MenuItem attr_accessor :id, :label, :url, :priority, :parent, :display_if_block, :children # Build a new menu item # # @param [Hash] options The options for the menu # # @option options [String, Proc] :label # The label to display for this menu item. It can either be a String or a # Proc. If the option is Proc, it is called each time the label is requested. # # @option options [String] :id # A custom id to reference this menu item with. If empty an id is automatically # generated for you. # # @option options [String, Symbol] :url # A string or symbol representing the url for this item. If it's a symbol, the # view will automatically call the method for you. # # @option options [Integer] :priority # MenuItems are sorted by priority then by label. The lower the priority, the # earlier in the menu the item will be displayed. # Default: 10 # # @option options [Proc] :if # A block for the view to call to decide if this menu item should be displayed. # The block should return true of false # # @option options [Proc] :parent # The parent label to display for this menu item. Menu item will be nested # under that label. It can either be a String or a Proc. If the option is Proc, # it is called each time the label is requested. def initialize(options = {}) @label = options[:label] @id = MenuItem.generate_item_id(options[:id] || label) @url = options[:url] @priority = options[:priority] || 10 @children = Menu::ItemCollection.new @parent = options[:parent] @display_if_block = options[:if] yield(self) if block_given? # Builder style syntax end def self.generate_item_id(id) id.to_s.downcase.gsub(" ", "_") end def label case @label when Proc @label.call else @label.to_s end end def add(*menu_items) menu_items.each do |menu_item| menu_item.parent = self @children << menu_item end end def children @children.sort end def parent? !parent.nil? end def dom_id id.gsub( " ", '_' ).gsub( /[^a-z0-9_]/, '' ) end # Returns an array of the ancestory of this menu item # The first item is the immediate parent fo the item def ancestors return [] unless parent? [parent, parent.ancestors].flatten end # Returns the child item with the name passed in # @blog_menu["Create New"] => <#MenuItem @name="Create New" > def [](id) @children.find_by_id(id) end def <=>(other) result = priority <=> other.priority result = label <=> other.label if result == 0 result end # Returns the display if block. If the block was not explicitly defined # a default block always returning true will be returned. def display_if_block @display_if_block || lambda { |_| true } end end end