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