codeplant/simple-navigation

Duplicate classes for menu item (possible problem in method SimpleNavigation::Item.html_options)

kirillsalikhov opened this issue · 2 comments

I use custom renderer, and in some places has double classes('selected selected').
May be problem in SimpleNavigation::Item.html_options, if I call it twice I get double classes
(if I set any html options in navigation.rb for item).

def html_options
      // Here, if my options[:html] is not blank, I get Link not copy to @options[:html]
      html_opts = options.fetch(:html) { Hash.new } 
      html_opts[:id] ||= autogenerated_item_id

      classes = [html_opts[:class], selected_class, active_leaf_class]
      classes = classes.flatten.compact.join(' ')
      // And at this place, it modifies @options[:html], If I call this method second time, it will be       
      // doubled(selected_class and active_leaf_class will be added second time)
      html_opts[:class] = classes if classes && !classes.empty? 

      html_opts
    end
andi commented

Not sure if I understand correctly. Can you provide the full code of your renderer?

class WgMenuRenderer < SimpleNavigation::Renderer::Base

  def render(item_container)
    if skip_if_empty? && item_container.empty?
      ''
    else
      tag = options[:ordered] ? :ol : :ul
      content = list_content(item_container)
      dom_attributes = item_container.dom_attributes
      nav_list = 'nav-list'
      if item_container.level > 1
        nav_list = 'nav-sublist'
      end
      dom_attributes[:class] = dom_attributes[:class].to_s + " #{nav_list} level-#{item_container.level}"
      dom_attributes[:class].strip!
      content_tag(tag, content, dom_attributes)
    end
  end

  private

  def list_content(item_container)
    items_tags = item_container.items.map { |item|
      # item.html_options used only once because it modificated from call to call
      html_options = item.html_options

      position = self.options[:position]
      if position != html_options[:position] && html_options[:position]
        next
      end

      li_options = html_options.except(:link)
      li_content = tag_for(item)

      active_class = html_options[:inactive] ? ' temp-disabled': ''

      li_class = ' nav-item' + active_class
      if item_container.level == 1 && item.selected? == true
        li_class += ' current-nav-item'
      end
      if item_container.level > 1
        li_class = ' sublist-item' + active_class
      end
      if include_sub_navigation?(item)
        li_content << render_sub_navigation_for(item)
        li_class += ' with-children'
      end
      li_options[:class]  = li_options[:class].to_s + "#{li_class}"
      li_options[:class].strip!

      content_tag(:li, li_content, li_options)
    }
    items_tags.delete_if(&:blank?).join
  end
end

navigation.rb

SimpleNavigation::Configuration.run do |navigation|
  navigation.id_generator = Proc.new {|key| "#{key}"}

  navigation.items do |primary|
    primary.item :menu_item_about, 'About', page_path('about'), :html => {position: :left} do |sub_nav|
       sub_nav.item :menu_item_dummy_1, 'docs', docs_path
    end

    primary.item :menu_item_flats, 'Flats', flats_path , :html => {position: :left} do |sub_nav|
      sub_nav.item :menu_item_dummy_1, 'design', page_path('facing')      
    end

    primary.item :menu_item_way, 'Works', works_path , :html => {position: :left}

    primary.item :menu_item_events, 'Events', news_index_path , :html => {position: :right} do |sub_nav|
      sub_nav.item :menu_item_dummy_1, 'Heart days', page_path('heart_days')
    end

    primary.item :menu_item_meaning, 'Meaning', page_path('meaning') , :html => {position: :right}
    primary.item :menu_item_connection, 'Contacts', page_path('contacts') , :html => {position: :right}

  end
end