I have some static pages in a navigation menu. I want to add a class like \"current\" to the item which is currently displaying.
The way I am doing so is to add tons
Here is the full example, on how to add an active class on bootstrap menu page in rails view.
<li class="<%= 'active' if current_page?(root_path) %>"><%= link_to 'Home', controller: "welcome" %></li>
<li class="<%= 'active' if current_page?(about_path) %>"><%= link_to 'About us', about_path %></li>
<li class="<%= 'active' if current_page?(contact_path) %>"><%= link_to 'Contact us', contact_path %></li>
I have a more succinct version of nav_link that works exactly like link_to, but is customized to output a wrapping li tag.
Put the following in your application_helper.rb
def nav_link(*args, &block)
if block_given?
options = args.first || {}
html_options = args.second
nav_link(capture(&block), options, html_options)
else
name = args[0]
options = args[1] || {}
html_options = args[2]
html_options = convert_options_to_data_attributes(options, html_options)
url = url_for(options)
class_name = current_page?(url) ? 'active' : nil
href = html_options['href']
tag_options = tag_options(html_options)
href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
"<li class=\"#{class_name}\"><a #{href_attr}#{tag_options}>#{ERB::Util.html_escape(name || url)}</a></li>".html_safe
end
end
If you look at the above code and compare it to the link_to code in url_helper.rb, the only difference is that it checks if the url is the current page, and adds the class "active" to a wrapping li tag. This is because I'm using the nav_link helper with Twitter Bootstrap's nav component which prefers links to be wrapped inside li tags and the "active" class applied to the outer li.
The nice thing about the above code is that it allows you to pass in a block into the function, just like you can do with link_to.
For example, a bootstrap nav list with icons would look like:
Slim:
ul.nav.nav-list
=nav_link root_path do
i.icon-home
| Home
=nav_link "#" do
i.icon-user
| Users
Output:
<ul class="nav nav-list">
<li class="active">
<a href="/">
<i class="icon-home"/>
Home
</a>
</li>
<li>
<a href="#">
<i class="icon-users"/>
Users
</a>
</li>
</ul>
In addition, just like the link_to helper, you can pass in HTML options into nav_link, which will be applied to the a tag.
An example of passing in a title for the anchor:
Slim:
ul.nav.nav-list
=nav_link root_path, title:"Home" do
i.icon-home
| Home
=nav_link "#", title:"Users" do
i.icon-user
| Users
Output:
<ul class="nav nav-list">
<li class="active">
<a href="/" title="Home">
<i class="icon-home"/>
Home
</a>
</li>
<li>
<a href="#" title="Users">
<i class="icon-users"/>
Users
</a>
</li>
</ul>
Use the current_page? helper to determine whether or not you should assign the "current"
class. For example:
<%= 'active' if current_page?(home_about_path) %>
Note you can also pass a path (not only a hash of options), e.g: current_page?(root_path)
.
According to the answer by Skilldrick, I'll change it to the following:
def nav_link(*args, &block)
is_active = current_page?(args[0]) || current_page?(args[1])
class_name = is_active ? 'active' : nil
content_tag(:li, class: class_name) do
link_to *args, &block
end
end
to make it much more useful.
Yep! Check out this article: A Better Way to Add a ‘selected’ Class to Links in Rails
Drop nav_link_helper.rb into app/helpers and it can be as easy as:
<%= nav_link 'My_Page', 'http://example.com/page' %>
The nav_link helper works just like the standard Rails link_to helper, but adds a 'selected' class to your link (or its wrapper) if certain criteria are met. By default, if the link's destination url is the same url as the url of the current page, a default class of 'selected' is added to the link.
There's a gist here: https://gist.github.com/3279194
UPDATE: This is now a gem: http://rubygems.org/gems/nav_link_to
This version is based on @Skilldrick's one but allows you to add html content.
Thus, you can do:
nav_link "A Page", a_page_path
but also:
nav_link a_page_path do
<strong>A Page</strong>
end
or any other html content (you can add an icon for instance).
Here the helper is:
def nav_link(name = nil, options = nil, html_options = nil, &block)
html_options, options, name = options, name, block if block_given?
options ||= {}
html_options = convert_options_to_data_attributes(options, html_options)
url = url_for(options)
html_options['href'] ||= url
class_name = current_page?(url) ? 'current' : ''
content_tag(:li, :class => class_name) do
content_tag(:a, name || url, html_options, &block)
end
end