navigation - generate - rails routes
La mejor forma de agregar clase "actual" a nav en Rails 3 (24)
¡Sí! Echa un vistazo a este artículo: una mejor forma de agregar una clase ''seleccionada'' a los enlaces en rieles
Coloque nav_link_helper.rb en la aplicación / ayudantes y puede ser tan fácil como:
<%= nav_link ''My_Page'', ''http://example.com/page'' %>
El navegador nav_link funciona igual que el Rails link_to helper estándar, pero agrega una clase ''selected'' a su enlace (o su contenedor) si se cumplen ciertos criterios. De forma predeterminada, si la URL de destino del enlace es la misma url que la url de la página actual, se agrega una clase predeterminada de ''seleccionado'' al enlace.
Hay una esencia aquí: https://gist.github.com/3279194
ACTUALIZACIÓN: ahora es una joya: http://rubygems.org/gems/nav_link_to
Tengo algunas páginas estáticas en un menú de navegación. Quiero agregar una clase como "actual" al elemento que se muestra actualmente.
La forma en que lo estoy haciendo es agregar toneladas de métodos auxiliares (cada uno para un elemento) para verificar el controlador y la acción.
def current_root_class
''class="current"'' if controller_name == "homepage" && action_name == "index"
end
<ul>
<li <%= current_root_class %>><%= link_to "Home", root_path %>
¿Hay alguna forma mejor de hacerlo? Mi manera actual es tan estúpida ......
¿La página current_page?
El método no es lo suficientemente flexible para mí (digamos que estableces un controlador pero no una acción, entonces solo regresará verdadero en la acción de índice del controlador), así que lo hice basado en las otras respuestas:
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
Ejemplo:
nav_link_to "Pages", pages_url, :controller => ''pages''
Aquí está el ejemplo completo sobre cómo agregar una clase activa en la página del menú de arranque en la vista de rieles.
<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>
Así es como lo resolví en mi proyecto actual.
def class_if_current_page(current_page = {}, *my_class)
if current_page?(current_page)
my_class.each do |klass|
"#{klass} "
end
end
end
Entonces..
li = link_to company_path
class: %w{ class_if_current_page( { status: "pending" }, "active" ), "company" } do
Current Company
Cree un método en ApplicationHelper
como a continuación.
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
Ahora úselo a la vista como en los casos de uso a continuación.
1. Para todas las acciones de cualquier controlador específico
<li class="<%= active(''controller_name'')%>">
....
</li>
2. Para todas las acciones de muchos controladores (con coma separada)
<li class="<%= active(''controller_name1,controller_name2'')%>">
....
</li>
3. Para acción específica de cualquier controlador específico
<li class="<%= active(''controller_name'', ''action_name'')%>">
....
</li>
4. Para acción específica de muchos controladores (con coma separada)
<li class="<%= active(''controller_name1,controller_name2'', ''action_name'')%>">
....
</li>
5. Para algunas acciones específicas de cualquier controlador específico
<li class="<%= active(''controller_name'', ''index, show'')%>">
....
</li>
6. Para algunas acciones específicas de muchos controladores (con coma separada)
<li class="<%= active(''controller_name1,controller_name2'', ''index, show'')%>">
....
</li>
Espero eso ayude
Creo que la mejor manera es
application_helper.rb:
def is_active(controller, action)
params[:action] == action && params[:controller] == controller ? "active" : nil
end
Y en el menú:
<li class="<%= is_active(''controller'', ''action'') %>">
Creo que se me ocurrió una solución simple que podría ser útil para muchos casos de uso. Esto me permite:
- Admite no solo texto plano, sino HTML dentro de
link_to
(por ejemplo, agrega un icono dentro del enlace) - Agregue solo algunas líneas de código a
application_helper.rb
- Agregar
active
al nombre de clase completo del elemento de enlace en lugar de ser la única clase.
Entonces, agregue esto a 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
Y en su plantilla puede tener algo como esto:
<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>
Como bonificación puede especificar o no un nombre de class_name
y usarlo así: <div class="<%= current_page?(root_path) %>">
Gracias a las respuestas anteriores 1 , 2 y resources .
Déjame mostrar mi solución:
_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
De acuerdo con la respuesta de Skilldrick , lo cambiaré a lo siguiente:
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
para hacerlo mucho más útil.
Esta versión está basada en la de @ Skilldrick, pero le permite agregar contenido html.
Por lo tanto, puedes hacer:
nav_link "A Page", a_page_path
pero también:
nav_link a_page_path do
<strong>A Page</strong>
end
o cualquier otro contenido html (puede agregar un ícono por ejemplo).
Aquí el ayudante es:
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
Hice un ayudante llamado 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
usado como:
nav_link ''Home'', root_path
que producirá HTML como
<li class="current"><a href="/">Home</a></li>
La forma en que lo hice es agregar una función auxiliar en application_helper
def current_class?(test_path)
return ''current'' if request.request_uri == test_path
''''
end
Luego en el navegador,
<%= link_to ''Home'', root_path, :class => current_class?(root_path) %>
Esto prueba la ruta del enlace contra el uri de la página actual y devuelve su clase actual o una cadena vacía.
No lo he probado a fondo y soy muy nuevo en RoR (me estoy moviendo después de una década con PHP) así que si esto tiene un defecto importante, me encantaría escucharlo.
Al menos de esta manera solo necesitas 1 función de ayuda y una simple llamada en cada enlace.
Mi manera fácil -
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
Gracias.
No es realmente una respuesta aquí, porque estoy usando la misma manera que tú. Acabo de definir métodos de ayuda para probar múltiples controladores o acciones:
En application_helper.rb
def controller?(*controller)
controller.include?(params[:controller])
end
def action?(*action)
action.include?(params[:action])
end
Entonces puedes usar if controller?("homepage") && action?("index", "show")
en tus vistas u otros métodos de ayuda ...
Para construir la respuesta de @Skilldrick ...
Si agrega este código a application.js, se asegurará de que cualquier menú desplegable con hijos activos también se marque como activo ...
$(''.active'').closest(''li.dropdown'').addClass(''active'');
Para recapitular el código de soporte> Agregar un ayudante llamado 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
usado como:
nav_link_to ''Home'', root_path
que producirá HTML como
<li class="active"><a href="/">Home</a></li>
Personalmente, utilicé una combinación de respuestas aquí
<li class="<%= ''active'' if current_page?(inventory_index_path) %>"><a href="#">Menu</a></li>
Estoy utilizando materializar CSS y mi manera de hacer que las principales categorías sean colapsables es usando el siguiente código
$(''.active'').closest(".collapsible.collapsible-accordion")
.find(".collapsible-header")
.click();
Espero que ayude a alguien
Sé que es una respuesta desactualizada, pero puede ignorar fácilmente toda esta comprobación de página actual utilizando un link_to helper wrapper, llamado active_link_to gem, funciona exactamente como usted desea, agregue una clase activa al enlace de la página actual
Si también quieres admitir hash de opciones html en la vista. Por ejemplo, si desea llamarlo con otra clase CSS o id, puede definir la función auxiliar de esta manera.
def nav_link_to(text, url, options = {})
options[:class] ||= ""
options[:class] += " active"
options[:class].strip!
link_to text, url, options
end
Entonces, en la vista, llama a este ayudante de la misma manera que llamarías link_to helper
<%= nav_link_to "About", about_path, class: "my-css-class" %>
Tengo una versión más concisa de nav_link que funciona exactamente como link_to, pero está personalizada para producir una etiqueta de envoltura li.
Coloque lo siguiente en su 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
Si mira el código anterior y lo compara con el código link_to en url_helper.rb, la única diferencia es que comprueba si la url es la página actual y agrega la clase "activa" a una etiqueta de envoltura li. Esto se debe a que estoy usando el navegador nav_link con el componente de navegación de Twitter Bootstrap, que prefiere enlaces para ser envueltos dentro de etiquetas li y la clase "activa" aplicada al límite externo.
Lo bueno del código anterior es que te permite pasar un bloque a la función, tal como lo puedes hacer con link_to.
Por ejemplo, una lista de navegación bootstrap con iconos se vería así:
Delgado:
ul.nav.nav-list
=nav_link root_path do
i.icon-home
| Home
=nav_link "#" do
i.icon-user
| Users
Salida:
<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>
Además, al igual que el link_to helper, puede pasar opciones HTML a nav_link, que se aplicará a la etiqueta a.
Un ejemplo de pasar un título para el ancla:
Delgado:
ul.nav.nav-list
=nav_link root_path, title:"Home" do
i.icon-home
| Home
=nav_link "#", title:"Users" do
i.icon-user
| Users
Salida:
<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>
Use la current_page?
ayudante para determinar si debe o no asignar la clase "current"
. Por ejemplo:
<%= ''active'' if current_page?(home_about_path) %>
Tenga en cuenta que también puede pasar una ruta (no solo un hash de opciones), por ej .: current_page?(root_path)
.
Uso una gema impresionante llamada Tabs on Rails .
Utilizo esta función nav_link (texto, enlace) en application_helper.rb (Rails 3) para hacer el trabajo y para mis enlaces de barra de navegación bootstrap 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
Ejemplo:
<%=nav_link("About Us", about_path) %>
Utilizo un ayudante simple como este para enlaces de nivel superior, por lo que la página /stories/my-story
resalta el enlace /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
todo esto funciona con barras de navegación simples, pero ¿qué pasa con el menú desplegable? cuando se selecciona un submenú, el elemento del menú superior debe estar ''actual'', en este caso tabs_on_rails yo seré la solución