This plugin is now available at GitHub. Follow all plugin modifications there (the SVN repo will soon be obsolete).
It seems like I’ve been going on and on about navigation in Rails lately. That’s probably because I have been. But it’s one of those things that presents itself in every app I work on. And since I usually go about it close to the same way, it makes a good case for a plugin, don’t you think? I shall call it, navigation helper. Clever, I know.
It’s pretty basic, but I’ll go through a few examples, anyway. Before I continue, two notes about these examples:
- whenever you see
navigation(...), think of <%= navigation(...) -%> as that method is a helper used in a view
- assume the current page will always be ‘Home’
Now that we have that settled, let’s see a few examples.
Basic Usage
This is how most people would probably use this plugin:
navigation [:home, :about, :contact_me]
You must use symbols as the links/sections, and we’ll see why in just a bit. Also, notice how :contact_me turns into ‘Contact Me’ as link text. You can use CSS to transform it to all lowercase or all uppercase, but the default is to capitalize each word (which you can’t do with CSS).
Oh, and the above example would be looking for the following named routes: home_path, about_path, and contact_me_path. So make sure you have a named route for each section you pass to the helper.
Authorized Sections
I don’t know about you, but a lot of the time I have one or two tabs that only appear based on some sort of authorization. For example, this very site has ‘Portfolio’, ‘Words’, ‘Archives’, and ‘About’ at the top. But if I’m logged in it also has ‘Admin’. Again, that’s a common need for me, so I added in support for that. Use it like so:
navigation [:home, :about, :admin], :authorize => [:admin]
navigation [:home, :about, :users, :reports], :authorize => [:users, :reports]
The plugin will only add those sections to the list if they are authorized. And how does it “authorize”? Well, by default the plugin will check against a logged_in? method. If that method either doesn’t exist or fails (returns false), those tabs will not be added. “But Ryan, don’t you think it’s kind of wrong of you to assume that we’re using a logged_in? method?” Well, maybe, maybe not. Either way, you can override that by telling the helper which method to use, like so:
navigation [:home, :about, :admin], :authorize => [:admin], :with => :auth_method
Now auth_method will be checked instead of logged_in?.
One more thing. In the case that the entire navigation is to be authorized, there is a way to avoid re-typing all of those sections in :authorize option.
navigation [:home, :about, :admin], :authorize => [:all]
Adding Subtitles
This was a recent need of mine (in the Portfolio). What I mean by subtitles is text that supports each link, but is not part of the link itself. That may have not helped you at all. Maybe this example will:
navigation [:home, 'Start Here', :about, 'Learn More']
Then you can do some fancy CSS :hover styling or whatever. Sometimes that adds just enough spice to a boring navigation bar.
But wait, there’s a second option. If you want the subtitles to appear as hover text instead, just let the helper know:
navigation [:home, 'Start Here', :about, 'Learn More'], :hover_text => true
And as I briefly mentioned above, that is why you have to pass symbols as the link/section and strings as the subtitles. The plugin understands symbols and strings differently (the positions matter, too: even for sections, odd for subtitles).
Setting Current Tab
OK, the last thing. By default the plugin uses the controller’s name to determine the “current” tab (or link or section) you’re on. But since that’s not always feasible, you can specify the current tab for any controller by doing:
class PublicController < ApplicationController
current_tab :home
end
Now something like this will work as intended:
navigation [:home, :about, :contact_me]
The PublicController will be seen as :home to the navigation helper, and will choose the current tab accordingly.
Documentation
All (or most) of the above is in the README. It’s on the agile web development site, too (although it doesn’t provide much info).
Installation
If you think this plugin could help you out, by all means install it. Here’s how:
ruby script/plugin install http://svn.rpheath.com/code/plugins/navigation_helper
...or…
piston import http://svn.rpheath.com/code/plugins/navigation_helper vendor/plugins/navigation_helper
Conclusion
I have a few more things I want to do with this plugin (such as sub-navigation), but I didn’t want to get unnecessarily complex just yet. Feel free to modify the code to your needs, and let me know if there’s something you absolutely think should be added/changed/fixed. Who knows, I just might do it! Enjoy.