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 Gemfile
:
gem 'simple-navigation'
Then, run 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
Enjoy! :)