Alacarte

Alacarte allows you to setup menus and conditions in your Rails app in a router-like DSL way.

You can easily;

  • group menus by name
  • set conditions on menu items as a group
  • set conditions on menu items with :if and :unless
  • nest your menus

Installation

Alacarte is being developed against Rails 3.0.3. No other versions have been tested.

To install, add Alacarte to your Gemfile and run `bundle install`:


gem 'alacarte'

After alacarte is installed, you will need to setup a rails initialiser to define your menu.

Initialiser

Add an initialiser file to your rails application; e.g. config/initialisers/alacarte.rb and add the menus in that file using the draw method.


YourApplication::Application.menus.draw do
    menu :main do
        # menu information goes here...
    end
end

How it works

Helper environment

Alacarte is linked to your helper environment, therefore you can call any helper method that is available to your rails app within your menu definition file;

  • format helpers
  • url_for, generated paths based on your routes file, …
  • I18n
  • authentication related calls (e.g. current_user for Devise or Authlogic)

options

You can pass in options to any level of your menu, including the top level. Here are some examples of options;

  • type specify what type it is, currently menu, link and span are supported
  • name allows you to specify the name of the menu item, a deep_name is derived, based on the parents of that item.
  • path allows you to set the path of that link
  • label sets the label of the menu. By default Alacarte tries to translate the deep_name (with an alacarte.menus namespace)
  • html are options passed in as html options to the given element (e.g. class or id attributes)
  • group are options passed in as html options, when the current element apears to be a group of other elements
  • if allows you to pass in a proc to test if the menu item is valid
  • unless allows you to pass in a proc to test if the menu item is valid, but tests for a false

Menu example


YourApplication::Application.menus.draw do

    menu :language do
        link :nl, root_path(:locale => :nl), :html => { :class => 'nl' }
        link :fr, root_path(:locale => :fr), :html => { :class => 'fr' }
    end

    menu :main, :group => { :class => 'main' } do
       link :home, root_path
       link :recent, 
       link :other_site, 'http://someurl.com'
       # ...
       
       # add menu items with runtime methods for path generation
       link :my_account, lambda { account_path(current_user) }, :if => lambda{ current_user }
       
    end
    
end

Render the menu

Render the menu where you like in your view and pass an optional “current element” selector (in this case the current locale);


...
    <div id="language_selection">
        <%= navigation_for(:language, I18n.locale) %>
    </div>
...

Output example

The output is generated as a ul-li list with anchor elements. If there is an element that can be matched, it will get a class active;


<ul>
    <li><a href="/" class="nl active">nl</a></li>
    <li><a href="/" class="fr">fr</a></li>
</ul>