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

Posted

技术标签:

【中文标题】如何以 DRY 方式基于 current_page 将“活动”类应用于我的导航? - 导轨 3【英文标题】:How do I apply an 'active' class to my navigation based on the current_page in a DRY way? - Rails 3 【发布时间】:2011-12-07 06:51:03 【问题描述】:

所以在我的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 助手将如下所示:

link_to "Profile", vanity_path(:vname =&gt; current_user.username), :class =&gt; "active".

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

谢谢。

【问题讨论】:

可能重复? :***.com/questions/7294181/… 还是这个问题? ***.com/questions/3705898/… 【参考方案1】:

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

这是我过去尝试过的

自从我使用 HAML 以来,我已经创建了一个返回带有 :class 定义的哈希的帮助程序

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

以前的用法:

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

或类似的替代方案

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

以前的用法:

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

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

【讨论】:

喜欢这个,但ERB 版本会是什么样子?我看不出这个版本和 ERB 版本之间有什么区别……但是鉴于您指定使用 HAML,这让我感到奇怪。【参考方案2】:

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

Answer taken from here


您可以使用 helper 来处理“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>

为了哈姆尔

看起来很简单:

%ul.nav
  %liclass: current_page?(some_path) && 'active'
    = link_to "About Us", some_path

【讨论】:

【参考方案3】:

你可以在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>

希望对你有帮助!

【讨论】:

【参考方案4】:

为什么不直接从 if else 块中取出多余的部分呢?也看看'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 模式匹配的链接中。

【讨论】:

这是一个有趣的解决方案。从来不知道link_to_unless。感谢那。至于 jQuery,如果我不需要的话,我宁愿不使用 JS……即如果有 Rails 方式,我宁愿先使用它。

以上是关于如何以 DRY 方式基于 current_page 将“活动”类应用于我的导航? - 导轨 3的主要内容,如果未能解决你的问题,请参考以下文章

以 DRY 方式创建活动/存档模型 (Django)

以 DRY 方式将多个错误类传递给 ruby​​ 的救援子句

如何在 Typescript 中保持代码 DRY 的同时解析多个 Json 文件?

如何让 C++ 与 DRY 完美契合? [关闭]

Rails 以 DRY 形式链接模型

从 Rails 设置 document.domain 的 DRY 方式