在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> 
希望能帮助到你