如何以DRY方式基于current_page将“活动”类应用于导航? - Rails 3

时间:2011-10-13 20:28:05

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.1

所以在我的application.html.erb中,我的导航结构看起来像这样:

<div id="navigation">
            <ul class="pills">
                    <% if current_page?(:controller => 'welcome', :action => 'index') %>
                        <li><%= link_to "Profile", vanity_path(:vname => current_user.username) %></li>
                        <li><%= link_to "Settings", settings_path %></li>
                        <li><%= link_to "Sign Out", signout_path %></li>
                    <% elsif !current_page?(:controller => 'welcome', :action => 'index') %>
                        <li><%= link_to "Home", root_path %></li>
                        <li><%= link_to "Profile", vanity_path(:vname => current_user.username) %></li>
                        <li><%= link_to "Settings", settings_path %></li>
                        <li><%= link_to "Sign Out", signout_path %></li>              
                    <% end %>
            </ul>
        </div>

但是,我想要做的是,一旦它们出现在导航的任何页面上,它就会将类active应用于相应的链接。

例如,如果用户在mydomain.com/johnbrown上是Profile链接,则rails helper看起来像这样:

link_to "Profile", vanity_path(:vname => current_user.username), :class => "active"

但是我如何以程序化的方式做到这一点,所以我不是在复制内容?即如何为导航中的所有页面获取该功能并尽可能将其写为DRY?

感谢。

4 个答案:

答案 0 :(得分:6)

这是一个非常好的问题。我从来没有真正对我见过或想出的解决方案感到满意。也许我们可以在这里一起来。

这是我过去尝试的内容

我做了一个帮助器,它返回一个哈希:class,因为我使用了HAML

def active_tab(path)
  request.path.match(/^#{path}/) ? { :class => 'active' } : {}
end

ex usage:

= link_to "Dashboard", dashboard_path, active_tab("#{dashboard_path}$")

或沿同一行的替代方案

def active_class(path)
  request.path =~ /#{path}/ ? 'active' : nil
end

ex usage:

= link_to 'Presentations', admin_presentations_path, :class => "#{active_class('presentations')}"

我很想看到其他一些建议。

答案 1 :(得分:3)

我找到了与引导程序相关的导航栏的答案,但您可以轻松地将其与导航器一起使用。

Answer taken from here


您可以使用帮助程序处理“current_page?”,例如方法:

module ApplicationHelper

 def is_active?(link_path)
  if current_page?(link_path)
    "active"
  else
    ""
  end
 end

end

示例bootstrap navbar

<div class="navbar">
  <div class="navbar-inner">
    <a class="brand" href="#">Title</a>
    <ul class="nav">
      <li class="active"><a href="#">Home</a></li>
      <li><a href="#">Link</a></li>
      <li><a href="#">Link</a></li>
    </ul>
  </div>
</div>

所以,在视图上看起来像

<li class="<%= is_active?(some_path) %>">
<%= link_to "name path", some_path %>
</li>

对于Haml

看起来很简单:

%ul.nav
  %li{class: current_page?(some_path) && 'active'}
    = link_to "About Us", some_path

答案 2 :(得分:0)

为什么不直接从if块中取出冗余部分?另请查看'link_to_unless'

 <div id="navigation">
        <ul class="pills">

                    <li><%= link_to_unless(current_page?(:controller => 'welcome', :action => 'index'), "Home", root_path %></li>

                   <li><%= link_to "Profile", vanity_path(:vname => current_user.username) %></li>
                    <li><%= link_to "Settings", settings_path %></li>
                    <li><%= link_to "Sign Out", signout_path %></li> 
        </ul>
    </div>

然后我会添加一些jQuery来将活动类注入到与window.location模式匹配的链接中。

答案 3 :(得分:0)

您可以在application_helper.rb

中定义辅助方法
def create_link(text, path)
  class_name = current_page?(path) ? 'my_class' : ''

  content_tag(:li, class: class_name) do
    link_to text, path
  end
end

现在您可以使用:

create_link 'xyz', any_path将呈现为

<li class="my_class">
  <a href="/any">xyz</a>
</li>

希望它有所帮助!