Andrew Rodland

NAME

WWW::MenuGrinder::Extending - Writing your own grinder plugins.

VERSION

version 0.06

DESCRIPTION

This document explains some of the things you will need to know if you want to write plugins that extend the functionality of WWW::MenuGrinder.

Plugins

A WWW::MenuGrinder plugin is a Perl class that uses Moose and consumes the role WWW::MenuGrinder::Role::Plugin (or, much more likely, one of its derived roles), and conforms to a certain interface. For more in-depth information on a given plugin type, see the documentation for the corresponding role.

Plugin Names

If your plugin is named WWW::MenuGrinder::Plugin::Foo users can easily load it by adding "Foo" to their plugins list. However it's not necessary to use the global namespace. If you write a plugin that's specific to MyApp, you might call it MyApp::MenuGrinder::Plugin::Frobnicate, and indicate it in the plugins list by preceding the fully qualified class name with a + sign.

Plugin Dependencies

A plugin may declare its dependency on another plugin by providing a plugin_depends method returning a list of strings. Each string in the list is a plugin name and is parsed in the same way as plugins given in the config. If a plugin A depends on a plugin B, it is guaranteed that B will be loaded before A's constructor is called (if B can't be loaded, then A's load will fail with a distinctive message), and that B will come before A in any processing chains (such as mogrify).

Control Flow

Load-Time

  • Plugin Initialization

    When the init method is called, the grinder reads its config and loads each plugin specified in the config in turn. Plugin dependencies are resolved after the requiring plugin's class is loaded, but before the requiring plugin's constructor is called.

  • Plugin Verification

    Plugins and Plugin roles may provide a verify_plugin method, to be called after the plugin and its dependencies have all been initialized. The purpose of this method is to ensure that contracts (such as required methods of the MenuGrinder object or of the plugin itself) are met at load time, in order to avoid surprises later.

  • Loading

    Once the plugins are loaded, the Loader plugin has its load method called. This method is expected to return a menu structure (conventionally a hashref) for all further plugins to work with.

  • Before Pre-Mogrify

    With the menu loaded, each PreMogrifier plugin is given a chance to do initialization. Each plugin will have its before_pre_mogrify method called, if that method exists. No arguments are passed and the method isn't permitted to modify the menu structure.

  • Pre-Mogrify

    Next, PreMogrifier plugins do initial transformation of the menu object. Each plugin has its pre_mogrify method called in turn on the menu object. pre_mogrify can modify the menu argument in-place, or completely recreate it; in either case it returns the menu object for the next plugin to process.

    • Item Pre-Mogrify

      The bundled Visitor plugin does tree-traversal, and calls the item_pre_mogrify method on any plugin consuming the ItemPreMogrifier role. This processing happens wherever Visitor is loaded in the plugin chain -- this is immediately before the first ItemPreMogrifier plugin, if it's not specified in the plugins list explicitly.

      XXX write more about how this is called.

Request Time

  • Before Mogrify

    As with BeforePreMogrify, each Mogrifier plugin gets a chance to do per-request initialization by implementing the before_mogrify method. This method takes no arguments and shouldn't modify the menu object.

  • Mogrify

    Next, each Mogrifier plugin modifies the menu structure using information from the current request. Each Mogrifier plugin in turn has its mogrify method called with the menu object; as with pre_mogrify, it should modify the menu object in place or copy it, and return the new object.

    • Item Mogrify

      The bundled Visitor plugin does tree-traversal, and calls the item_mogrify method on any plugin consuming the ItemMogrifier role. This processing happens wherever Visitor is loaded in the plugin chain -- this is immediately before the first ItemMogrifier plugin, if it's not specified in the plugins list explicitly.

      XXX write more about how this is called.

  • Output

    Lastly in the processing chain, the Output plugin is called. There is only one output plugin, and it is always last in the chain; therefore its output isn't required to be valid input to any other plugin, as with other plugins. The return value of the output plugin's output method will be returned from the grinder object's get_menu method.

  • Cleanup

    Finally, the cleanup method is called for each plugin, if it exists, allowing the plugin to discard any state data that it no longer needs. Note that due to implementation details of web frameworks, the Cleanup phase might happen immediately before the request phase of the next request, rather than immediately after the current request.

AUTHOR

Andrew Rodland <andrew@hbslabs.com>

COPYRIGHT AND LICENSE

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.