John: Thanks for your interest in my modules. I have a working example, but it is not on the web. I will send you the code to try out. The modules are ready for release and I plan to make only few changes which will not affect the general interface.
Navigation.pm module can be used to manipulate any structure with parent-child relationships, not only navigation menus. It is a good idea to keep this structure in a database, but I intentionally did not provide any methods for databases to keep it simple and modular. Navigation::HTML render_menu() method provides only one of the ways to generate an HTML menu from the multi-level structure described in Navigation object. This method will need to be rewritten if you want to implement a different menu layout. This can be done, however, using other existing methods from this module. Regards, Arkady. On 24 Mar 2003, John Crowley wrote: > Arkady, > > Your posting comes just as I was about to sit down and contemplate this > problem for a medical site I'm working on. The Navigation.pm module > looks very interesting to me, especially since it looks like it would be > easy to assign parent-child relationships via some bill-of-materials SQL > queries. I'd love to see your solution. Do you have a working example on > the web? > > - John > > > ____________________ > > John Crowley > Concinnitas LLC > http://www.concinnitas.com > > > On Mon, 2003-03-24 at 01:44, Arkady Grudzinsky wrote: > > Hi, everyone. > > > > Most of us have to deal with some kind of multi-level navigation menus, > > which are not trivial to implement. This topic, of course, has been > > already addressed, but I have my own approach, which I have not seen in > > other modules. Please, review this documentation and let me know if these > > modules are worth publishing. Would you use them personally? > > > > Sincerely, > > > > Arkady. > > > > =========================================================================== > > Navigation documentation > > =========================================================================== > > > > NAME > > Navigation - Perl extension to manipulate multi-level navigation menus. > > > > SYNOPSIS > > use Navigation; > > my $menu = Navigation->new(); > > @keys = $menu->keys(@keys); > > $key_count = $menu->add_keys(@keys); > > %Parents = $menu->parents(%parents); > > $parent = $menu->parent($key, $parent); > > @children = $menu->children($key); > > @ancestors = $menu->ancestors($key); > > $level = $menu->level($key); > > > > DESCRIPTION > > This module provides methods which can be used to generate a multi-level > > navigation menu for any user interface, regardless of implementation. > > The module can be used to describe "parent-child" relationship between > > menu items and retrieve other items related to the selected item, such > > as its "parent", "children", "ancestors", or "siblings". > > > > Rendering of the menu is left to external modules to keep Navigation.pm > > implementation-independent. For example, module Navigation::HTML may > > associate a caption and a hyperlink with each item and implement > > rendering of the menu as a list of hyperlinks with some elements > > collapsed or expanded, depending on the preferred menu layout and > > behavior. > > > > RATIONALE > > This module implements my personal approach to describe the structure of > > a multi-level navigation menu (or any other structure with hierarchy) > > which I have not seen in other modules. The approach is to describe a > > multi-level navigation menu in general, using "parent - child" > > terminology and simple concepts from graph theory, independently of any > > specific application. > > > > EXPORT > > > > None. All methods are called from the object. > > > > DEFINITIONS > > A MENU is a list of ITEMS. Each item is identified by a KEY. Item A can > > be a list of other items (AA, AB, AC, ...), in which case item A is a > > PARENT of AA, AB, or AC; and the latter are CHILDREN of the former. If > > item AA has children AAA, AAB, and AAC, items A and AA are called > > ANCESTORS to either AAA, AAB, or AAC. The count of ancestors is this > > item's LEVEL (2 for AAA, 1 for AA, 0 for A). Items with no parents are, > > naturally, top-level items. AA, AB, and AC (sharing the same parent) are > > SIBLINGS (following the "parent-child" terminology). > > > > Navigation menu items are internally represented as an array of keys. > > Parents for each key are set using a hash of the form ($key => $parent). > > 'keys'=>[EMAIL PROTECTED] and 'parents'=>{%parents} are the only internal > > attributes of Navigation object. All methods are designed to manipulate > > these attributes. > > > > METHODS > > new() > > Creates a new Navigation object. > > > > keys(@keys) > > Accepts an array of keys as optional arguments. Supplied with @keys, > > sets keys to [EMAIL PROTECTED] replacing existing attribute. Returns the > > array > > of keys. Returns ('home') if no keys are set. > > > > add_keys(@keys) > > Adds optional array @keys to the existing array of keys. Returns > > count of keys. > > > > parent($key, $parent) > > Sets parent for the $key to $parent (if $parent is provided). > > Returns parent for $key. > > > > parents(%parents) > > Adds optional hash %parents = ($key => $parent) to the 'parents' > > hash. Returns the 'parents' hash; > > > > children($key) > > Returns array of children for item with $key. > > > > ancestors($key) > > Returns array of ancestors for the item with $key. Ancestors are > > traced up to the top level or until the first repeating ancestor to > > prevent loops. > > > > level($key) > > Returns the level of menu item with $key, determined by the count of > > ancestors. > > > > siblings($key) > > Returns an array of keys for the items of the same level as $key > > having the same parent. > > > > EXAMPLE > > use Navigation; > > > > # Create menu > > my $menu = Navigation->new(); > > > > # Define some keys > > $menu->keys('A', 'B', 'C'); > > > > # Add other items to the menu > > $menu->add_keys('AA', 'AB', 'AC', 'AAA', 'AAB', 'AAC'); > > > > # Define hierarchy > > $menu->parents('AA'=>'A', 'AB'=>'A', 'AC'=>'A'); > > $menu->parents('AAA'=>'AA', 'AAB'=>'AA', 'AAC'=>'AA'); > > > > # The following lines print out > > # 'AA' ancestors, 'AA' siblings, and 'AA' children: > > > > print $menu->ancestors('AA'); > > print $menu->siblings('AA'); > > print $menu->children('AA'); > > > > # These functions are used in external modules, such > > # as Navigation::HTML to render the menu. > > > > AUTHOR > > Arkady Grudzinsky, <[EMAIL PROTECTED]> > > > > SEE ALSO > > the perl manpage , the Navigation::HTML manpage. > > > > > > ==================================================================== > > Navigation::HTML documentation > > ==================================================================== > > > > NAME > > Navigation::HTML - Render multi-level navigation menu in HTML. > > > > SYNOPSIS > > use Navigation::HTML; > > my $menu = Navigation::HTML->new(); > > %captions = $menu->captions(%captions); > > $caption = $menu->caption($key, $caption); > > %links = $menu->links(%links); > > $link = $menu->link($key, $link); > > $class = $menu->class($class); > > $class_selected = $menu->class_selected($class); > > $item_pattern = $menu->item_pattern($pattern); > > $list_pattern = $menu->list_pattern($pattern); > > $menu_pattern = $menu->menu_pattern($pattern); > > $rendered_item = $menu->render_item($key, $pattern); > > $rendered_list = $menu->render_list($list, $pattern); > > $rendered_menu = $menu->render_menu($key); > > $mode_param = $menu->mode_param($mode_param); > > > > DESCRIPTION > > This module renders a multi-level navigation menu as customizable HTML > > code. Implementation-independent "parent-child" relationship between > > menu items is described using methods inherited from Navigation.pm. > > Navigation::HTML provides methods to assign a caption and a URL to each > > menu key and render items as HTML. > > > > This module deliberately provides no methods for visual formatting of > > the menu. All visual formatting (fonts, colors, etc.) is left for > > external cascading style sheets. It is possible to assign a class to > > menu elements with class() and class_selected() methods (see below). > > > > EXPORT > > > > None. All methods are called from object. > > > > METHODS > > captions(%captions) > > %captions is a ($key => $caption, ...) hash. captions() associates > > captions with menu keys adding to the existing captions without > > replacement. Returns the hash of existing captions. > > > > caption($key, $caption) > > If $caption is provided, associates $caption with the $key. Returns > > the caption for the key. This value is used to replace the > > '#caption' token in item pattern while rendering the menu (see > > below). If you assign no caption to a key, the $key value itself is > > returned. In this way, if your item keys are short and descriptive, > > you can save yourself trouble assigning captions. > > > > links(%links), link($key, $link) > > Associate URL with menu keys, similarly to caption() and captions(). > > The value returned by link($key) is used to replace the '#link' > > token in item pattern while rendering the menu (see below). If you > > do not assign a URL to a key, link() will return a default value > > "<script_name>?".$menu->mode_param()."=$key". E.g., if your script > > name is 'myscript.cgi' and you have not changed the default value of > > $menu->mode_param (which is "rm"), $menu->link('home') will return > > > > myscript.cgi?rm=home > > > > This default is provided for an easy use with Jesse Erlbaum's > > CGI::Application module. CGI::Application, however, is not required > > by Navigation::HTML. > > > > mode_param($mode_param) > > Sets the mode parameter value for the default output of link() > > method. Default mode_param value is "rm". > > > > class($class) > > If $class is provided, sets the 'class' attribute. Returns string > > "CLASS=<class>" where <class> is the value of the attribute. This > > string is used to replace the '#class' token in item, list, and menu > > patterns while rendering the menu (see below). If 'class' attribute > > is not set, returns "CLASS=menu". This class can be used in external > > cascading style sheets (CSS) for visual formatting of the menu. The > > only way to set visual formatting inside the object is incorporate > > visual formatting tags in item, list, and menu patterns, which is > > not recommended. > > > > class_selected($class) > > If $class is provided, sets the 'class_selected' attribute. Returns > > string "CLASS=<class_selected>" where <class_selected> is the value > > of the attribute. This string is used to replace the '#class' token > > in item patterns while rendering selected item and its ancestors > > instead of the value returned by class(). If 'class_selected' > > attribute is not set, returns "CLASS=menu_selected" string. > > > > item_pattern($pattern) > > By default, items are rendered as HTML string > > > > <li #class><a #class href=#link>#caption</a>#submenu</li>\n > > > > where "#class", "#link", and "#caption" are replaced with class(), > > link($key), and caption($key) values respectively. #submenu is > > replaced by a string formed during menu rendering to include menu > > items of the next level. This default item pattern can be changed by > > using this method with an argument. > > > > list_pattern($pattern) > > Sets pattern for rendering a list of items. By default, lists of > > items are rendered as HTML string > > > > \n<ul #class>\n#list\n</ul> > > > > where '#list' is replaced with a string of rendered list of items > > and '#class' is replaced by the output of class() method. > > > > menu_pattern($pattern) > > Sets pattern for rendering the menu. By default, returns the string > > > > <div #class>#menu</div> > > > > where '#class' is replaced with the output of class() method and > > '#menu' is replaced by the string containing the rendered menu. > > > > render_item($key, %attributes) > > %attributes = ( > > 'pattern' => $pattern, > > 'class' => $class, > > 'link' => $link, > > 'caption' => $caption, > > 'submenu' => $submenu > > ) > > > > %attributes is optional. render_item() returns a string generated by > > replacing tokens '#class', '#link', '#caption', and '#submenu' in > > $attributes{'pattern'} with respective values of %attributes. For > > missing values of %attributes, the values returned by > > item_pattern(), class(), link($key), and caption($key) are used. > > Such implementation allows deviations from default rendering for > > certain menu items (e.g. to include JavaScript). > > > > render_list($list, $pattern) > > Returns a string generated by replacing tokens '#class' and '#list' > > with the output of class() method and the string $list in $pattern. > > $pattern is optional argument. By default, the string returned by > > list_pattern() is used. > > > > render_menu($key) > > This method implements one of the possible ways to render a > > multi-level menu. In this implementation, the menu is rendered as > > unordered multi-level list with all items collapsed, except for the > > selected item $key and its ancestors. You may override this method > > in your own object or in a function inside of your application. > > > > Even if you don't use this method to render your menu, I hope that > > other methods and ideas provided in Navigation and Navigation::HTML > > will be useful for implementation of your multi-level navigation > > menus. > > > > AUTHOR > > Arkady Grudzinsky, <[EMAIL PROTECTED]> > > > > Comments, ideas and sarcastic remarks will be greatly appreciated. > > > > SEE ALSO > > the perl manpage, the Navigation manpage. > > > > > > > > > > > > > > --------------------------------------------------------------------- > > Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ > > To unsubscribe, e-mail: [EMAIL PROTECTED] > > For additional commands, e-mail: [EMAIL PROTECTED] > -- > John Crowley <[EMAIL PROTECTED]> > johncrowley.net > > > --------------------------------------------------------------------- > Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > > --------------------------------------------------------------------- Web Archive: http://www.mail-archive.com/[EMAIL PROTECTED]/ To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
