Waiter serves up menus for your application:
- Provides a quick DSL for building menus, without having to specify any HTML.
- Makes assumptions based on what's provided in the DSL so that the specification does not need to be unnecessarily verbose.
Add this line to your application's Gemfile:
And then execute:
Or install it yourself as:
$ gem install waiter
Building a menu
To create a new menu:
::.(:my_menu) do file edit view # ... end
The above defines a menu with three items. By default, each item name (ie. "file", "edit", etc.) corresponds both to the
I18n string to use (so
file will call
I18n.t(:file, scope: [:menu, :my_menu])) as well as to the controller to use
file will correspond to
FileController, and the menu item will link to
FileController#index by default).
Of course, there will be situations where the path may need to be explicitly specified. In this case, you can use a path finder:
:::: do .file documents_path end
:action options can be specified:
::. do .file :controller => :documents, :action => :index end
In both of the above examples, the File menu will correspond to
DocumentsController#index, and will be shown as selected
for any action within that controller.
There may also be times where you need multiple controllers to light up the same menu item. This can be achieved by
passing an array to the
Waiter::Menu.serve do file :controllers => ['files', 'print', ... ] end
This will create a menu that links to
DocumentsController#index, which will be lit up the user hits any action within
PrintController, as well as the
Menus can also have submenus (currently only one level of nesting is supported when drawing a menu, but infinite levels are supported when building a menu). A submenu is defined with the same syntax as a root menu item, and is passed as a block to the root menu item.
Submenus automatically assume the controller to use is the controller specified by its root menu item, so a
controller does not need to be specified unless it differs. As well, the menu item name is assumed to be used
for the controller for that item, so it does not need to be specified unless it differs from the name.
An id can also be specified if necessary (with the
::. do file do new # Corresponds to FileController#new print print_file_path # Corresponds to PrintController#print list :action => :all # Corresponds to ListController#all end end
If a path hash is given without an
action key, the index action will be inferred.
There are two options that you can use when building your menu. Options can be passed into build when defining a menu or specified once the menu is defined by accessing the menu.options hash.
selected: Allows the selected menu item to be overridden, so a specified menu item can be lit up regardless of
what the current controller/action is. This can be useful if there is an action that falls under different menu
items depending on application context, or if there is a controller that may correspond to multiple menu items.
A good way to achieve this would be to add a before_filter to set an instance variable which is then passed into
the selected option.
before_filter :set_current_menu def case params[:action] when 'foo' then @current_menu = "menu1" when 'bar' then @current_menu = "menu2" end end ::.(:selected => @current_menu) do || end
Note that the value passed to
:selected should match the name of the menu item.
Drawing (outputting) a menu
To draw a created menu, use the
Waiter::Menu::Drawer class. The class requires the current context to be
passed in so that
ActionController methods can be used. In general (ie. if the menu is being drawn from a helper)
the context is self.
= ::. do || # ... end ::::.(, context).
If a different
Drawer is desired,
Waiter::Menu::Drawer can be subclassed and the method
draw overridden to provide an alternate format.
Waiter::Menu responds to
- Fork it
- Create your feature branch (
git checkout -b my-new-feature)
- Commit your changes (
git commit -am 'Add some feature')
- Push to the branch (
git push origin my-new-feature)
- Create new Pull Request