Author image Andrew Rodland
and 1 contributors


WWW::MenuGrinder - A tool for managing dynamic website menus - base class.


version 0.06


  my $grinder = My::Subclass::Of::MenuGrinder->new(
    config => {
      plugins => {
        loader => 'XMLLoader',
        per_request => [
      filename => "/foo/menu.xml"

  # Some time later...
  my $menu = $grinder->get_menu


WWW::MenuGrinder is a framework for integrating menus into web applications.

MenuGrinder provides a framework for any number of plugins (from CPAN or the "using" application) to work with a tree structure representing a navigational method. Plugins may perform tasks such as loading a representation of the menu from disk, rendering the menu as HTML, conditionally displaying menu items based on user permissions, or determining the menu item corresponding to the "current page". MenuGrinder plugins on the CPAN may be found in the WWW::MenuGrinder::Plugin:: namespace.

MenuGrinder is intended to work well within web frameworks; currently there are glue classes for Catalyst on CPAN but it should work well within any system.

MenuGrinder uses Moose to make extending it as pleasant as possible!



Accessor. This is where the menu structure sits between "on load" processing and "per-request" processing.


Accessor. Is an arrayref containing instances of all of the loaded plugins, in the order they were specified in the config. More likely accessed via $grinder->plugins_with($role).


Utility function, maps a role name (Plugin) to the corresponding class name (WWW::MenuGrinder::Role::Plugin).


Returns an arrayref listing all of the registered plugin instances that consume the named role. Accepts the short name of a role.


Attempts to load the plugin given by $plugin. If $plugin begins with '+' then it is treated as a literal classname, otherwise it is prefixed with WWW::MenuGrinder::Plugin::. If the plugin is found:

  • The plugin is required.

  • Its plugin_depends, if any, are followed recursively.

  • The plugin is instantiated, with its config from $grinder->config (if any).

  • The plugin is asked to verify_plugin itself (may throw an exception).

  • The plugin is added to the grinder's list of registered plugins to be returned by $grinder->plugins and $grinder->plugins_with.

  • The plugin instance is returned.


Called on grinder construction. Reads the list of plugins from the config and attempts to load them. Throws an exception if anything seems to be amiss.


Called on grinder construction.

  • Invokes the Loader plugin to load the menu structure.

  • Invokes any "on_load" plugins to make initial modifications to the menu.

  • Invokes the on_init method of any plugins consuming the OnInit role.

$grinder->mogrify($menu, $stage, @plugins)

This is the main workhorse of MenuGrinder; given the menu structure and a list of plugins implementing Mogrifier or ItemMogrifier roles, it allows each plugin in turn to make modifications to the menu. ItemMogrifier plugins that fall adjacent to each other in the plugin chain may be run together on a single pass over the menu tree; to avoid this behavior separate the ItemMogrifier plugins by a Mogrifier plugin, perhaps the no-op WWW::MenuGrinder::Plugin::NullTransform.

$grinder->get_menu( [ $type ] )

Invokes all "per_request" plugins to modify a copy of the menu structure, possibly filters the menu through an Output plugin, then returns the result. The heuristic for choosing an output is slightly complex:

  • If the $type argument is provided then it is taken to be the name of the output plugin to use. If $type doesn't correspond to the name of a loaded Output plugin an error occurs.

  • If the $type argument is not provided and there is exactly one loaded Output plugin, that plugin is used.

  • Otherwise, the menu is returned unmodified.


Currently this is alpha code. I welcome any opinions, ideas for extensions, new plugins, etc. However, documentation is incomplete, tests are nonexistent, and interfaces are subject to change. don't use this in production unless you want to get yourself in deep.



Andrew Rodland <>


This software is copyright (c) 2011 by HBS Labs, LLC..

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.