NAME

CGI::Explorer - A class to manage a tree of data, for use in CGI scripts

VERSION

This document refers to version 1.00 of CGI::Explorer, released 24-02-2001.

SYNOPSIS

This is tested code, altho the she-bang (#!) must start in column 1:

#!D:/Perl/Bin/Perl

use integer;
use strict;
use warnings;

use CGI;
use CGI::Explorer;

my($q)		= CGI -> new();
my($tree)	= CGI::Explorer -> new();
my($dir)	= 'D:/My Documents/HomePage';

$tree -> from_dir($dir);

my($state)		= $tree -> state($q); # Must follow from_dir() or from_hash().
my($tree_set)	= $tree -> as_HTML($q);
my($result_set)	= 'Id: ' . $tree -> current_id() . '. Name: ' . $tree -> name();

print	$q -> header(),
		$q -> start_html(),
		$q -> start_form({action => $q -> url()}),
		$q -> hidden({name => 'explorer_state', value => $state, force => 1}),
		$q -> table
		(
			{border => 1},
			$q -> Tr
			([
				$q -> td($tree_set) .
				$q -> td($result_set),
			])
		),
		$q -> end_form(),
		$q -> end_html();

DESCRIPTION

CGI::Explorer is a support module for CGI scripts. It manages a tree of data, so that the script can display the tree, and the user can click on a node in the tree to open or close that node.

Opening a node reveals all children of that node, and restores their open/close state.

Closing a node hides all children of that node.

Overview

CGI::Explorer reconstructs its internal representation of the tree each time the script is invoked.

Some of data comes from the script calling $tree -> from_directory(...) or $tree -> from_hash(...), and some of the data comes from CGI form fields returned from the previous invocation of the script.

Specifically, the open/closed state of each node is sent on a round trip from one invocation of the script out to the browser, and, via a 'form submit', back to the next invocation of the script.

Also, clicking on a node on a form submits the form, and passed the id of the node so clicked back to the second invocation of the script.

State maintenance - a complex issue - is discussed further below. See the 'state' method.

Constructor and initialization

new(...) returns a CGI::Explorer object.

This is the class's contructor.

A call to new() is equivalent to:

new(a_href => 0, image_dir => '/images', show_current => 1, show_id => 1, show_name => 1)

Options:

  • a_href - Default is 0

    Make the displayed name of the node an anchor.

  • image_dir - Default is '/images'

    Specify the web server's directory in which the node icons are to be found.

    Note: This is not the operating system path of the directory, it is the path relative to the web server's document root.

  • show_current - Default is 1

    Show a special icon for the 'current' node.

  • show_id - Default is 1

    Show the id of the node, to the right of the node's icon.

  • show_name - Default is 1

    Show the name of the node, to the right of the node's icon, and to the right of the node's id (if show_id == 1).

    If show_id == 0 && show_name == 0, nothing is displayed.

Icons for Nodes

CGI::Explorer ships with a set of icons, with a PNG and a GIF for each icon.

The default is GIF, because more browsers support GIF transparency than support PNG transparency.

You don't have to pay UniSys a licence for usage of the GIF compression algorithm, because the GIFs are uncompressed :-).

The make file does not install these files automatically. You must install them manually under the web server's document root, and then use the image_dir option to point to the directory containing these files.

Many GIFs are from a package called MySQLTool. Unfortunately the authors of this program have forgotten to put a download URI in their package. You may get some joy here: http://lists.dajoba.com/m/listinfo/mysqltool.

I've renamed their files from the names used by MySQLTool.

The icons for the root node, and for the current node, are not quite satisfactory. Let me know if you have better ones available.

If the transparent PNG does not display properly on your browser, which is likely, update the browser, or try using the GIFs.

Almost all icons are constrained to a size of 17 x 17. The exception is the icon for the root, which is unconstrained, so that you may use any image you wish.

as_HTML($q)

Returns a string.

Converts the internal representation of the data into HTML, and returns that.

_build_result(...)

Used internally.

current_id()

Returns the id of the 'current' node.

_found()

Used internally.

Called by File::Find, which means it does not receive $self as its first parameter, which means in turn that it must use the class global $myself to access class data.

from_dir($dir_name)

Returns nothing.

Tells the object to construct its internal representation of the data by parsing the names of all sub-directories in the given directory.

Usage:

  • $tree -> from_directory('/home/rons');

  • $tree -> from_directory('D:\My Documents');

  • $tree -> from_directory('D:/My Documents');

You call as_HTML($q) later to retrieve a printable version of the data.

See ce.pl for an example.

from_hash($hash_ref)

Returns nothing.

Tells the object to construct its internal representation of the data by extracting information from the given hash.

You would call as_HTML($q) later to retrieve a printable version of the data.

Each key in %$hash_ref is a unique integer, 1 .. N, and points to a hash ref with these sub keys:

  • id - A unique integer, 1 .. N, different for each node

    This is the identifier of this node.

    Warning: There must be a node with id == 1.

    Yes, this is a copy of the key within $hash_ref, for use within Tree::Nary-dependent code.

  • name - A string

    This is the (displayed) name of this node.

  • parent_id - An integer, 0 .. N

    This is the identifier of the parent of this node.

    The relationship between id and parent_id is what makes the data a tree.

    0 means the node has no parent, ie this node is a child of a virtual root node. By virtual, I mean each CGI::Explorer object creates its own root node, so that you do not have to.

    If you do have your own root node, with id 1 (say), then your root node's parent will still be 0, and your next-level nodes will all have a parent id of 1.

See ce.pl for an example.

name()

Returns the name of the 'current' node.

parent_id()

Returns the id of the parent of the 'current' node.

set()

Returns nothing.

Used to set a new value for any option, after a call to new().

set() takes the same parameters as new().

state($q)

Returns the open/closed state of all nodes.

Tells the object to update its internal representation of the data by recovering CGI form field data from the given CGI object.

Warning: You must use the return value as a field, presumably hidden, in a form, in your script so that the value can do a round trip out to the browser and back. This way the value can be recovered by the next invocation of your script.

This is the mechanism CGI::Explorer uses to maintain the open/closed state of each node. State maintenance is a quite a complex issue. For details, see:

Writing Apache Modules with Perl and C
Lincoln Stein and Doug MacEachern
O'Reilly
1-56592-567-X
Chapter 5 'Maintaining State'

You can see the problem: When you close and then re-open a node, you expect all child nodes to be restored to the open/close state they were in before the node was closed.

With a program like Windows Explorer, this is simple, since the program remains in RAM, running, all the time nodes are being clicked. Thus it can maintain the state of each node in its own (process) memory.

With a CGI script, 2 separate invocations of the script must maintain state outside their own memory. I have chosen to use (hidden) form fields in CGI::Explorer.

See ce.pl for an example.

The form fields have these names:

  • explorer_id_(\d+) - The id of the node clicked on

    There is 1 such form field per node.

    The click on this node is what submitted the form. (\d+) is a unique integer 1 .. N.

    Your CGI script does not need to output these form fields. as_HTML($q) does this for you.

  • explorer_state - The open/closed state of all nodes. Its value is a string

    Your CGI script must output this value. See above.

Required Modules

  • Tree::Nary. Not shipped with Perl. Get it from a CPAN near you

AUTHOR

CGI::Explorer was written by Ron Savage <ron@savage.net.au> in 2001.

Home page: http://savage.net.au/index.html

COPYRIGHT

Copyright &copy; 2001, Ron Savage. All rights reserved.

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