Problems with submenu rendering. Menu is built dynamically

240 views
Skip to first unread message

sigm...@gmail.com

unread,
Aug 29, 2012, 4:29:41 PM8/29/12
to simple-n...@googlegroups.com
Hello

I build menu dynamically using data from database.

This is @menu variable:
==========
- :key: main1
  :name: Home
  :url: /
- :key: main2
  :name: Services
  :url: /user-research
  :items:
  - :key: sub1
    :name: User research
    :url: /user-research
    :highlights_on: !ruby/regexp /\/user-research/
  - :key: sub2
    :name: Usability review
    :url: /usability-review
    :highlights_on: !ruby/regexp /\/usability-review/
  - :key: sub3
    :name: Interface design
    :url: /user-interface-design
    :highlights_on: !ruby/regexp /\/user-interface-design/
  - :key: sub4
    :name: Usability and UX courses
    :url: /usability-training
    :highlights_on: !ruby/regexp /\/usability-training/
- :key: main3
  :name: Our projects
  :url: /portfolio
- :key: main4
  :name: Contacts
  :url: /contacts
- :key: main5
  :name: Feedback
  :url: /testimonials
- :key: main6
  :name: About
  :url: /about
==========

This is what I have in template:
==========
<%= render_navigation :level => 1, :items => @menu %>
<%= render_navigation :level => 2, :items => @menu %>
==========

When I open /user-research-full (I should not put in menu), "Services" menu item is not highlighted and submenu is not shown.

If to write hardcode everything is fine:
==========
navigation.items do |primary|    
    primary.item :portfolio, "Главная", root_path
    primary.item :services, "Услуги", static_path("user-research"), :highlights_on => /\/services/ do |sub_nav|
      sub_nav.item :analysis_of_audience, "Анализ пользователей", static_path("user-research"), :highlights_on => /\/user-research/
      sub_nav.item :ux_review, "Юзабилити-аудит", static_path("usability-review"), :highlights_on => /\/usability-review/
      sub_nav.item :ui_design, "Проектирование интерфейсов", static_path("user-interface-design"), :highlights_on => /\/user-interface-design/
      sub_nav.item :'usability-training', "Обучение", static_path("usability-training"), :highlights_on => /\/usability-training/
    end
    primary.item :portfolio, "Наши работы", projects_path
    primary.item :testimonials, "Отзывы", testimonials_path
    primary.item :about, "О нас", static_path(:about)
    primary.item :contacts, "Контакты", static_path(:contacts)
end
==========

But I need to build menu dynamically. 

Simple Navigation  version is 3.7.0.

Could you help me to solve this problem?

Andi Schacke

unread,
Aug 30, 2012, 2:34:33 AM8/30/12
to simple-n...@googlegroups.com
Hi there,

I didn't have time yet to anaylize your problem in great detail. But maybe the problem is that the content of your @menu variable is yaml. It should be a Hash. There is even an easier way: in the master branch (currently not released as gem, I will release 3.9.0 on the weekend) there is a new option: You can pass a block to render_navigation to dynamically build your navigation:

render_navigation :level => 1 do |primary|
  primary.item …
  primary.item …
end

The syntax is the same as in the config file. 

If you don't want to specify the block again for your two render_navigation calls, you can define a method that return the block, e.g.

def my_dynamic_menu
  Proc.new do |primary|
     primary.item...
  end
end

and then you call

render_navigation :level => 1, &my_dynamic_menu
render_navigation :level => 2, &my_dynamic_menu

As I said, the gem for this is not released yet, so to do this, you have to add this to your gemfile:

gem 'simple-navigation', :git => 'git://github.com/andi/simple-navigation.git'

I hope this helps!
Andi

--
You received this message because you are subscribed to the Google Groups "simple-navigation" group.
To view this discussion on the web visit https://groups.google.com/d/msg/simple-navigation/-/-JB3Vb58ExQJ.
To post to this group, send email to simple-n...@googlegroups.com.
To unsubscribe from this group, send email to simple-navigat...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/simple-navigation?hl=en.

sigm...@gmail.com

unread,
Sep 7, 2012, 4:12:08 AM9/7/12
to simple-n...@googlegroups.com
No. This is @menu.to_yaml(). I often use this format for debugging. It is more handy than inspect().

Your solution did the job. The problem was in strange behavior of highlights_on if to use hash. I made block instead of hash and everything is working good.

Thank you very much for quick response!

Andi Schacke

unread,
Sep 7, 2012, 4:35:57 AM9/7/12
to simple-n...@googlegroups.com
That's good to hear. By the way: the newest gem (3.9.0) includes the new "block" feature.

Andi

To view this discussion on the web visit https://groups.google.com/d/msg/simple-navigation/-/nNzpQFOlKhEJ.

extreme....@gmail.com

unread,
Jul 19, 2013, 4:06:40 AM7/19/13
to simple-n...@googlegroups.com, sigm...@gmail.com
Hi,

I am busy working on building a dynamically generated menu and I have gone through the documentation but do not quite understand how the use of a Proc will generate the dynamic menu. From what I understand of the example, each item is still manually declared within the Proc (am I still a little new to Ruby so may just be confused).

I have a database table that holds various dynamic pages for a website (table columns being:  "id, "parent_id", "name", "content") and there can theoretically be an infinite number of nested pages. Past programming experience tells me that this is a suitable situation for recursion and do I have simple recursive method defined which more or less should do what I think (haven't been able to test it out yet as I dont think simple-navigation likes it) but this is it here:

SimpleNavigation::Configuration.run do |navigation|
  navigation.items do |primary|

     # recursive function to generate the pages
    def walktree(db, parent)
      sub_items = pages_menu.where(parent_id: db.id)
      if sub_items.count > 0
        parent.item db.name,db.name,pandora_content_path(db.id), class: "has-dropdown" do |s|
          s.dom_class="dropdown"
          sub_items.each do |ddItem|
            walktree(ddItem, s)
          end
        end
      else
        parent.item db.name,db.name,pandora_content_path(db.id)
      end
    end

    #generate dynamic pages menus
    pages_menu.where(parent_id: nil).each do |menu|
      if menu.is_visible
        walktree(menu, primary)
      end
    end

  end
end

Since navigation.rb is just a ruby file and going by ruby logic that everything in ruby is an object, I do not see why I should not be able to do something similar to this. 

Any insight you could provide me with would be most appreciated.

Kind regards,
Braden

extreme....@gmail.com

unread,
Jul 19, 2013, 4:28:42 AM7/19/13
to simple-n...@googlegroups.com, sigm...@gmail.com, extreme....@gmail.com
Never mind.. I got it working. Was a bug in my model code.. A fully dynamic menu can be done using the below code:

SimpleNavigation::Configuration.run do |navigation|
  navigation.items do |primary|

    def walktree(db, parent)
      sub_items = pages_menu.where(parent_id: db.id)
      if sub_items.count > 0
        parent.item db.name,db.name,my_content_path(db.id), class: "has-dropdown" do |s|
          s.dom_class="dropdown"
          sub_items.each do |ddItem|
            walktree(ddItem, s)
          end
        end
      else
        parent.item db.name,db.name,my_content_path(db.id)
      end
    end

    primary.dom_class='right'

    #dynamic pages menus
    pages_menu.where(parent_id: '0').each do |menu|
Reply all
Reply to author
Forward
0 new messages