Generating your site menu with the 'simple-navigation' gem
January 3, 2012
This post was originally published in the Rambling Labs Blog on January 3, 2012.
One of the cool things I learned while building our new site was how to generate your site navigation menu without having to do the highlighting logic yourself.
There’s a great gem out there for this called
simple-navigation, which you can find on GitHub. It’s easy to set up and use, so you will probably do what you need to do really quick. To install, add it to your rails application
bundle install. After it’s installed, generate the configuration file for it, which will be the
config/navigation.rb, with the following:
rails generate navigation_config
Go ahead and open the
config/navigation.rb file, and add your navigation items, which in my case is the following:
SimpleNavigation::Configuration.run do |navigation| navigation.selected_class = 'current' navigation.items do |primary| primary.item :menu_home, 'Home', root_path primary.item :menu_about_us, 'About Us', about_us_path primary.item :menu_blog, 'Blog', posts_path primary.item :menu_contact_us, 'Contact Us', contact_us_path end end
As you may have noticed, I don’t have to specify when to be highlighted. This is because the gem assumes, by convention, that each navigation item will only be highlighted when its url matches the current url being accessed. Great! That’s less navigation code for me to write.
Ah, but wait, I want my blog navigation item to be highlighted whenever your accessing any url under
/blog. Fair enough,
simple-navigation supports a
highlights_on option, which can be passed either a regular expression to match with the current url or a lambda that will determine if it’s highlighted. I changed the blog navigation to this:
navigation.items do |primary| # ... primary.item :menu_blog, 'Blog', posts_path, highlights_on: /\/blog/ # ... end
Where they completely bought me in was with the navigation rendering. To render your navigation menu, just write this:
<%= render_navigation %>
And that’s it! Awesome, right?
In case you want to define navigation levels, just pass a block to the
primary.item definition, like this:
navigation.items do |primary| # ... primary.item :menu_blog, 'Blog', posts_path, highlights_on: /\/blog/ do |blog| blog.item :menu_popular, 'Popular', popular_posts_path blog.item :menu_recent, 'Recent', recent_posts_path end # ... end
You can find more documentation on the simple navigation’s wiki