4

I have a simple menu that looks like this:

<ul class="menu">
     <li class="active"><a href="<%= root_path %>">Home</a></li>
     <li class=""><%= link_to 'Feeds' , feeds_path %></li>
     <li class=""><%= link_to 'Accounts' , accounts_path %></li>
</ul>

Class "active" is the style to mark my current page.

I have two questions:
1. How do I "tell" the app what page I am on and ask it to "change" the class to active?
2. Is there a better way to create this menu (maybe driven by the controller or a db table)?

I realize this is a newbie question, but I have been thinking about this for a few days now, have read some tutorials, but none of them really click.

Thanks for your help.

Michaerr
  • 241
  • 3
  • 12
  • a possible alternative is to use yield like house9 answer http://stackoverflow.com/questions/8625829/design-pattern-for-side-bar-with-dynamic-content-in-rails/8626755#8626755 – Hishalv Mar 12 '12 at 19:37

4 Answers4

1

I use the method current_page? to set my active link. It takes a path as its parameter. I create a hash of link texts and paths and iterate over it printing the links. That way I only have to call current_page? one time.

There are gems that can help you, though. Look through these: https://www.ruby-toolbox.com/categories/rails_menu_builders

JohnColvin
  • 2,489
  • 1
  • 14
  • 8
1

I have done this recently in ApplicationHelper:

  def nav_links
    items = [home_link, about_me_link, contact_link]
    content_tag :ul, :class => "nav" do
      items.collect { |item| concat item}
    end
  end

  def home_link
    nav_item_active_if(!@article || @article.type.nil?) do
     link_to "Home", root_path
    end
  end

  def about_me_link
    nav_item_active_if(@article && @article.type == "About") do
      link_to "About Me", article_path(About.first)
    end
  end

  def contact_link
    nav_item_active_if(@article && @article.type == "Contact") do
      link_to "Contact", article_path(Contact.first)
    end
  end

  def nav_item_active_if(condition, attributes = {}, &block)
    if condition
      attributes["class"] = "active"
    end
    content_tag(:li, attributes, &block)
  end

In your view you can simply call:

      <%= nav_links %>

You can maybe use it as an example.

Ch4rAss
  • 754
  • 3
  • 18
0

Not a perfect solution, but you could do the following.

create 3 variables:

@homeActive = ""
@feedsActive = ""
@accountsActive = ""

In the code you provided, set the class to each variable corresponding with name.

<li class=@homeActive><a href="<%= root_path %>">Home</a></li>

Now in your controller under the home method lets say, set @homeActive = "active", and the other two to "". Repeat for the other methods and this should work.

challeng
  • 175
  • 1
  • 8
0

I used a bunch of 'if's and the current_page? method. It's ugly but it worked, if someone has a better idea how to do this, I will be happy to learn about it.

if current_page? (root_path)
   content_tag(:li , link_to('Home' , root_path), :class => "active")
 else
   content_tag(:li , link_to('Home' , root_path))
end
Michaerr
  • 241
  • 3
  • 12