it-swarm-pt.tech

Melhor maneira de destacar a página atual no Rails 3? - aplica uma classe css a links condicionalmente

Para o seguinte código:

<%= link_to "Some Page", some_path %>

Como aplico uma classe css current usando o método auxiliar current_page?‎?

Ou se alguma outra maneira melhor está disponível?

47
Jacob

Em app/helpers/application_helper.rb

def cp(path)
  "current" if current_page?(path)
end

Em seus pontos de vista:

<%= link_to "All Posts", posts_path, class: cp(posts_path) %>

Basicamente, escreva um simples wrapper em torno dele. Além disso, você pode estender o método para permitir que classes adicionais sejam aplicadas adicionando argumentos. Mantém as visualizações concisas/secas. Ou, sem estender o método, você poderia apenas fazer uma simples interpolação de String para adicionar classes adicionais:

<%= link_to "All Posts", posts_path, class: "#{cp(posts_path)} additional_class" %>
89
Michael van Rooijen

No meu caso eu tenho um monte de controladores de nomes espaçados, é por isso que eu gosto de mostrar se a view atual também está no caminho do menu, eu usei a solução do Michael van Rooijen e depois eu customizei para o meu caso.

Ajudante

def cp(path)
  "current" if request.url.include?(path)
end

Visão

<%= link_to "All Posts", posts_path, class: cp(posts_path) %>

Agora, se minha barra de menu é/users e minha página atual é/users/10/post também o link/users é definido com a classe "atual" 

18
rderoldan1

Saí da resposta de Michael e ajustei o ajudante:

def active_class?(*paths)
  active = false
  paths.each { |path| active ||= current_page?(path) }
  active ? 'active' : nil
end

Veja como você o usaria:

<%= link_to "Bookings", bookings_path, class: active_class?(bookings_path) %>

Você pode passar vários caminhos para ele caso tenha uma guia que possa ser renderizada por várias visualizações:

<%= content_tag :li, class: active_class?(bookings_path, action: 'new') %>

E o melhor disso é que se as condições forem false, ele irá inserir nil. Por que isso é bom? Bem, se você fornecer class com nil, ele não incluirá o atributo de classe na tag. Bônus!

10
Eric Boehs

No interesse de não ter que se repetir muito por ter que verificar current_page dentro do método link_to o tempo todo, aqui está um auxiliar personalizado que você pode usar (coloque isso em app/views/helpers/application_helpers.rb

def link_to_active_class(name, active_class_names, options = {}, html_options = {}, &block)
  html_options[:class] = html_options[:class].to_s + active_class_names if current_page?(options.to_s)
  link_to name, options, html_options, &block
end

Exemplo de uso:

<div> <%= link_to_active_class('Dashboard', 'bright_blue', dashboard_path, class: 'link_decor') </div>

se você está em http://example.com/dashboard, então deve retornar:

<div> <a href='/dashboard' class='link_decor bright_blue'>Dashboard</a> </div>

Saudações.

4
Nik So

Eu faria assim:

<%= link_to "Some Page", some_path, :class => current_page? ? "current" : "" %>
3
thoferon

Tentei combinar algumas das técnicas mencionadas com minhas próprias necessidades.

def current_page(path)
  'current' if current_page?(path)
end

def create_nav_link(string, path, method)
  link_to string, path, data: { hover: string }, method: method
end

def create_nav_item(string, path, method = nil)
  content_tag :li, create_nav_link(string, path, method), class: current_page(path)
end

Basicamente, ele permite que você o use assim: create_nav_item("profile", profile_path) que resultará em: <li><a href="/profile" data-hover="Profile">Profile</a></li>,

ou <li class="current"><a href="/profile" data-hover="Profile">Profile</a></li> se esta for a página atual.

Eu não usei request.url.include?(path), pois ele também sempre destaca o botão "Home", e eu não conseguia pensar em um trabalho de longe.

0
Glubi

Eu acho que seria uma boa idéia se você gerasse todo link_to do seu método auxiliar. Por que repetir o mesmo código (:-) DRY princípio)

def create_link(text, path)
  class_name = current_page?(path) ? 'current' : 'any_other_class'

  link_to text, path, class: class_name
end

Agora você pode usar como:

<%= create_link 'xyz', any_path %> (em views) que renderizaria como <a href="/any" class="current">xyz</a>

Espero que ajude!

0
Dusht

Uma variante da solução de Eric Boehs (a mais robusta IMHO), se você estiver vinculando diretamente a um objeto da classe (ou seja, você não mostra o índice), com um auxiliar de aplicativo adicionado:

def booking_link
 Booking.find(8)
end

Você pode usar o seguinte na exibição (o dd é usado no contexto da fundação zurb)

<%= content_tag :dd, link_to(t('hints.book'), booking_link), class: active_class?(booking_path) %>-
0
Jerome