在Rails 3中将“当前”类添加到nav的最佳方法

我在导航菜单中有一些静态页面。 我想添加一个像“当前”类到当前正在显示的项目。

我这样做的方法是添加大量的辅助方法(每个项目)来检查控制器和操作。

def current_root_class 'class="current"' if controller_name == "homepage" && action_name == "index" end <ul> <li <%= current_root_class %>><%= link_to "Home", root_path %> 

有没有更好的方法来做到这一点!? 我现在的路很愚蠢……

这里不是一个真正的答案,因为我使用的方式和你一样。 我刚刚定义了帮助程序方法来testing多个控制器或操作:

在application_helper.rb中

  def controller?(*controller) controller.include?(params[:controller]) end def action?(*action) action.include?(params[:action]) end 

那么你可以在你的视图或其他辅助方法中使用if controller?("homepage") && action?("index", "show")

我做了一个名为nav_link的助手:

 def nav_link(link_text, link_path) class_name = current_page?(link_path) ? 'current' : '' content_tag(:li, :class => class_name) do link_to link_text, link_path end end 

用于:

 nav_link 'Home', root_path 

这将产生像HTML一样的HTML

 <li class="current"><a href="/">Home</a></li> 

使用current_page? 助手来确定你是否应该分配"current"类。 例如:

 <%= 'active' if current_page?(home_about_path) %> 

注意你也可以传递一个path(不仅是选项的散列),例如: current_page?(root_path)

我在application_helper.rb(Rails 3)中使用了这个nav_link(text,link)函数来完成工作,并为我启动了引导twitter 2.0导航栏的链接。

 def nav_link(text, link) recognized = Rails.application.routes.recognize_path(link) if recognized[:controller] == params[:controller] && recognized[:action] == params[:action] content_tag(:li, :class => "active") do link_to( text, link) end else content_tag(:li) do link_to( text, link) end end end 

例:

 <%=nav_link("About Us", about_path) %> 

我做的方法是在application_helper中添加一个辅助函数

 def current_class?(test_path) return 'current' if request.request_uri == test_path '' end 

然后在导航中,

 <%= link_to 'Home', root_path, :class => current_class?(root_path) %> 

这将testing当前页面的链接pathuri,并返回当前类或空string。

我没有彻底地testing过,而且我对RoR也很陌生(用了十年的PHP),所以如果这有一个重大的缺陷,我很乐意听到它。

至less这样,你只需要1个帮助函数和每个链接中的简单调用。

build立@Skilldrick的答案…

如果你将这段代码添加到application.js中,它将确保任何带有活动子项的下拉菜单也将被标记为活动状态。

 $('.active').closest('li.dropdown').addClass('active'); 

回顾支持代码>添加名为nav_link的帮助程序:

 def nav_link_to(link_text, link_path) class_name = current_page?(link_path) ? 'active' : '' content_tag(:li, :class => class_name) do link_to link_text, link_path end end 

用于:

 nav_link_to 'Home', root_path 

这将产生像HTML一样的HTML

 <li class="active"><a href="/">Home</a></li> 

我认为最好的办法是

application_helper.rb:

 def is_active(controller, action) params[:action] == action && params[:controller] == controller ? "active" : nil end 

在菜单中:

 <li class="<%= is_active('controller', 'action') %>"> 

我知道这是一个过时的答案,但你可以很容易地忽略所有这些当前页面检查通过使用link_to辅助包装,称为active_link_togem,它的作品正是你想要的,添加一个活跃的类到当前页面链接

我使用了一个名为Tabs on Rails的真棒gem。

下面是完整的示例,介绍如何在rails视图的引导菜单页面上添加活动类。

  <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> 

current_page? 方法对我来说不够灵活(比如说你设置了一个控制器而不是一个动作,那么它只会在控制器的索引动作上返回true),所以我根据其他的答案做了这个:

  def nav_link_to(link_text, link_path, checks=nil) active = false if not checks.nil? active = true checks.each do |check,v| if not v.include? params[check] active = false break end end end return content_tag :li, :class => (active ? 'active' : '') do link_to link_text, link_path end end 

例:

 nav_link_to "Pages", pages_url, :controller => 'pages' 

我有一个更加简洁的nav_link版本,其工作方式与link_to完全相同,但是可以自定义输出一个包装li标签。

把下面的代码放在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 

如果您查看上面的代码并将其与url_helper.rb中的link_to代码进行比较,唯一的区别是它检查url是否为当前页面,并将类“active”添加到包装li标签。 这是因为我正在使用nav_link助手与Twitter Bootstrap的导航组件 ,喜欢链接被包裹在里面的标签和“积极”类应用到外部里。

上面代码的好处在于它允许你将一个块传递给函数,就像你可以用link_to一样。

例如,带有图标的引导程序导航列表将如下所示:

瘦:

 ul.nav.nav-list =nav_link root_path do i.icon-home | Home =nav_link "#" do i.icon-user | Users 

输出:

 <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> 

另外,就像link_to助手一样,你可以将HTML选项传递给nav_link,它将被应用到a标签。

为锚点传递标题的示例:

瘦:

 ul.nav.nav-list =nav_link root_path, title:"Home" do i.icon-home | Home =nav_link "#", title:"Users" do i.icon-user | Users 

输出:

 <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> 

是的! 看看这篇文章: 一个更好的方法来添加一个“选定”类到链接在Rails中

将nav_link_helper.rb拖放到app / helpers中,它可以像下面这样简单:

 <%= nav_link 'My_Page', 'http://example.com/page' %> 

nav_link助手的工作方式与标准的Rails link_to助手一样,但是如果满足某些条件,则会向链接(或其包装器)添加“selected”类。 默认情况下,如果链接的目标url与当前网页的url相同,则默认类为“已选”。

这里有一个要点: https : //gist.github.com/3279194

更新:这现在是一个gem: http : //rubygems.org/gems/nav_link_to

我使用这样一个简单的帮手来获得顶级链接,所以/stories/my-story页面突出显示了/stories链接

 def nav_link text, url active = (url == request.fullpath || (url != '/' && request.fullpath[0..(url.size-1)] == url)) "<li#{ active ? " class='selected'" : '' }><a href='#{url}'>#{text}</a></li>".html_safe end 

让我展示我的解决scheme:

_header.html.erb

  <ul class="nav"> <%= nav_tabs(@tabs) %> </ul> 

application_helper.rb

  def nav_tabs(tabs=[]) html = [] tabs.each do |tab| html << (content_tag :li, :class => ("current-page" if request.fullpath.split(/[\??]/)[0] == tab[:path]) do link_to tab[:path] do content_tag(:i, '', :class => tab[:icon]) + tag(:br) + "#{tab[:name]}" end end) end html.join.html_safe end 

application_controller.rb

 before_filter :set_navigation_tabs private def set_navigation_tabs @tabs = if current_user && manager? [ { :name => "Home", :icon => "icon-home", :path => home_index_path }, { :name => "Portfolio", :icon => "icon-camera", :path => portfolio_home_index_path }, { :name => "Contact", :icon => "icon-envelope-alt", :path => contact_home_index_path } ] elsif current_user && client? ... end 

对于我个人而言,我在这里使用了答案的组合

 <li class="<%= 'active' if current_page?(inventory_index_path) %>"><a href="#">Menu</a></li> 

我正在使用物化的CSS和我的方式使可折叠的主要类别是通过使用下面的代码

 $('.active').closest(".collapsible.collapsible-accordion") .find(".collapsible-header") .click(); 

希望它可以帮助别人

根据Skilldrick的回答 ,我会将其更改为以下内容:

 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 

使其更有用。

这个版本是基于@ Skilldrick的,但允许您添加html内容。

因此,你可以这样做:

nav_link "A Page", a_page_path

但也:

 nav_link a_page_path do <strong>A Page</strong> end 

或任何其他的HTML内容(例如,你可以添加一个图标)。

这里的帮手是:

  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 

所有这些工作与简单的导航栏,但下拉菜单呢? 当一个子菜单被选中的时候,顶层菜单项应该是“当前”,在这种情况下tabs_on_rails me是解决scheme

这是我在当前项目中解决的问题。

 def class_if_current_page(current_page = {}, *my_class) if current_page?(current_page) my_class.each do |klass| "#{klass} " end end end 

然后..

 li = link_to company_path class: %w{ class_if_current_page( { status: "pending" }, "active" ), "company" } do Current Company 

我简单的方法 –

application.html.erb

 <div class="navbar"> <div class="<%= @menu1_current %> first-item"><a href="/menu1"> MENU1 </a></div> <div class="<%= @menu2_current %>"><a href="/menu2"> MENU2 </a></div> <div class="<%= @menu3_current %>"><a href="/menu3"> MENU3 </a></div> <div class="<%= @menu4_current %> last-item"><a href="/menu4"> MENU4 </a></div> </div> 

main_controller.erb

 class MainController < ApplicationController def menu1 @menu1_current = "current" end def menu2 @menu2_current = "current" end def menu3 @menu3_current = "current" end def menu4 @menu4_current = "current" end end 

谢谢。

如果还想在视图中支持html选项散列。 例如,如果你想用其他CSS类或ID来调用它,你可以像这样定义helper函数。

 def nav_link_to(text, url, options = {}) options[:class] ||= "" options[:class] += " active" options[:class].strip! link_to text, url, options end 

所以在视图中,调用这个助手的方式和你调用link_to助手一样

 <%= nav_link_to "About", about_path, class: "my-css-class" %> 

我想我想出了一个简单的解决scheme,可能会有很多用例的帮助。 这让我:

  • 不仅支持纯文本,而且还支持link_to内的HTML(例如,在链接中添加一个图标)
  • application_helper.rb添加几行代码
  • active附加到链接元素的整个类名称,而不是唯一的类。

所以,添加到application_helper.rb

 def active_class?(class_name = nil, path) class_name ||= "" class_name += " active" if current_page?(path) class_name.strip! return class_name end 

在你的模板上,你可以有这样的东西:

 <div class="col-xs-3"> <%= link_to root_path, :class => active_class?("btn btn-outline-primary", root_path) do %> <i class="fa fa-list-alt fa-fw"></i> <% end %> </div> 

作为奖励,您可以指定或不指定class_name ,并像这样使用它: <div class="<%= current_page?(root_path) %>">

感谢以前的答案1,2和资源 。

ApplicationHelper创build一个方法如下。

 def active controllers, action_names = nil class_name = controllers.split(",").any? { |c| controller.controller_name == c.strip } ? "active" : "" if class_name.present? && action_names.present? return action_names.split(",").any? { |an| controller.action_name == an.strip } ? "active" : "" end class_name end 

现在在下面的用例中使用它。

1.针对任何特定控制器的所有操作

 <li class="<%= active('controller_name')%>"> .... </li> 

2.对于许多控制器的所有操作(用逗号分隔)

 <li class="<%= active('controller_name1,controller_name2')%>"> .... </li> 

3.任何特定控制器的具体行动

 <li class="<%= active('controller_name', 'action_name')%>"> .... </li> 

4.对于许多控制器的具体行为(用逗号分隔)

 <li class="<%= active('controller_name1,controller_name2', 'action_name')%>"> .... </li> 

5.对于任何特定控制器的某些特定操作

 <li class="<%= active('controller_name', 'index, show')%>"> .... </li> 

6.对于许多控制器的某些特定操作(用逗号分隔)

 <li class="<%= active('controller_name1,controller_name2', 'index, show')%>"> .... </li> 

希望能帮助到你