Ik vond dat het weer tijd was voor een nieuwe Rails helper. Dit keer een helper om een menu item te maken die automatisch een class ‘current’ meegeeft als de huidige URL overeenkomt met de meegestuurde URL. Het is niet de perfecte helper en zal niet voor alle situaties helpen, maar is zeker een goed beginpunt om te customizen. Ik heb de helper ‘menu_li’ genoemd.

def menu_li(label, url="/", *args)
   options = args.extract_options!
   current_page = request.request_uri
   current_check = (url == "/" ? current_page == "/" : current_page.match(url))
   options[:class] = current_check ? "current" : nil
   content_tag(:li, link_to(label, url, :title => label), options)
end

Je kunt nu dus het volgende doen om een menu item aan te maken.

<ul>
   <%= menu_li "Home" %>
   <%= menu_li "Posts", "/posts" %>
</ul>

Als je op de root van de website bent (“/”) dan krijg je de volgende HTML.

<ul>
   <li class="current"><a href="/" title="Home">Home</a></li>
   <li><a href="/posts" title="Posts">Posts</a></li>
</ul>

Als je dus in de index van de PostsController bent krijgt de tweede <li> een class ‘current’. Je kunt ook extra argumenten meegeven, waaronder een extra class.

<ul>
   <%= menu_li "Home" %>
   <%= menu_li "Posts", "/posts", :class => "andere_class" %>
</ul>

Als je in /posts zit dan wordt de class echter niet toegevoegd aan de <li>. De ‘current’ class herschrijft dan de opgegeven class. Als je dit niet wil kun je deze aangepaste helper gebruiken.

def menu_li(label, url="/", *args)
   options = args.extract_options!
   current_page = request.request_uri
   current_check = (url == "/" ? current_page == "/" : current_page.match(url))
   options[:class] = options[:class].blank? ? (current_check ? "current" : nil) : (current_check ? "#{options[:class]} current" : options[:class])
   content_tag(:li, link_to(label, url, :title => label), options)
end

Veel plezier met deze helper. Volgende keer weer een andere helper, dus blijf me volgen.