Navigation Bar no Rails
August 15th, 2008Esses dias eu achei um template pronto na internet (modestamente, sou um péssimo designer) que vinha com uma navbar. Achei bacana e comecei a pensar num jeito Rails de fazer algo bonitinho: ao clicar num item da navbar, esse item fica selecionado.
A primeira coisa que eu pensei, foi em algo como:
minha.url/do/site?current=ATUAL
Tendo, digamos, algo como HomeController, PostController e CommentController, ATUAL podia variar entre Home, Post e Comment. Uma solução, relativamente, clean. Então voltei à Ruby on Rails: Talk e fiz a pergunta: qual a melhor forma de abordar esse problema?
O resultado foi essa discussão: http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/0c0378e25f2d9343
O código que comentei na discussão é o que segue:
app/helpers/home_helper.rb
-
module HomeHelper
-
def build_navbar(items)
-
# If I reached the site right now, params[:current]
-
# is null.
-
params[:current] = "home" if params[:current].nil?
-
-
menu=""
-
-
items.each do |item|
-
menu += content_tag :li, :class => is_current?(item) do
-
link_to item, send( "#{item}_url", { :current => item } )
-
end
-
end
-
-
return menu
-
end
-
-
# Methods ending by ‘?’ returns either "true" or "false"
-
# But using it here in "other" context increases
-
# readbility.
-
def is_current?(item)
-
(item == params[:current]) ? "current" : nil
-
end
-
end
#app/views/layouts/post.html.erb
-
[…]
-
<div id="nav">
-
<ul>
-
<%= build_navbar %w(home posts articles photos) %>
-
</ul>
-
</div>
-
[…]
É um código bonitinho, até… Mas eu podia ter usado um params[:current] ||= “home”.
Mas esse código não funciona perfeitamente. Se eu entrar no site via minha.url/do/site/posts, por exemplo, params[:current] não está setada e será setada para “home”, apesar de eu não estar em HomeController.
Então eu comecei a pensar: o que eu posso fazer pra deixar esse código melhor e funcionando sempre? Eu tenho MESMO que usar algo feio como “?current=[home|post|whatever]”? O Rails não tem nada que facilite isso também?
Comecei a procurar no Google por isso. Não lembro as keywords, mas deve ter sido algo como “current controller name rails”, eu descobri um tal de controller.controller_name. E funciona muito bem.
O resultado?
-
module HomeHelper
-
# Build an navbar with items from the givem
-
# array. Current nav item would get an
-
# "current" CSS’ class.
-
def build_navbar(items)
-
menu=""
-
-
items.each do |item|
-
menu += content_tag :li, :class => is_current?(item) do
-
link_to item, send( "#{item}_url" )
-
end
-
end
-
-
return menu
-
end
-
-
# Methods ending by ‘?’ returns either "true" or "false"
-
# But using it here in "other" context increases
-
# readbility.
-
def is_current?(item)
-
(item == controller.controller_name) ? "current" : nil
-
end
-
end
MUITO melhor. ![]()
