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]
