如何以 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 => current_user.username), :class => "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 方式将多个错误类传递给 ruby 的救援子句