This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: CGI/EncryptForm,  Next: CGI/Enurl,  Prev: CGI/Debug,  Up: Module List

Implement trusted stateful CGI Form Data using cryptography.
************************************************************

NAME
====

   CGI::EncryptForm - Implement trusted stateful CGI Form Data using
cryptography.

SYNOPSIS
========

     use CGI::EncryptForm;
     
     my $cfo = new CGI::EncryptForm(secret_key => 'my secret');
     
     my $hashref = { username => 'joe', password => 'test' };

     my $encrypted_string = $cfo->encrypt($hashref);
     if (!defined($encrypted_string)) {
       print $cfo->error();
       return;
     }

     my $newhashref = $cfo->decrypt($encrypted_string);
     if (!defined($newhashref)) {
       print $cfo->error();
       return;
     }

     print $newhashref->{'username'};

PREREQUISITES
=============

   This modules requires the following perl modules:

   Digest::SHA1, Crypt::HCE_SHA and Storable

ABSTRACT
========

   Many CGI programmers take for granted the validity of stateful CGI form
data.

   Im talking about the common scenario where you present a form to the
browser, the user fills in the form, you verify the form values, store
them in the next form as hidden fields, the user fills in another form,
the script appends these results to the next form in hidden fields and so
on.

   Using hidden form fields is one mechanism where by CGI scripts can
maintain state in the process of collecting information from the user.

   Unfortunately, it is also one of the weakest to implement because the
CGI script must trust the hidden form fields and there values, provided by
the users browser. At some point in time the CGI program does something
with this stateful information. To be completely sure the hidden fields
haven't been altered along the way and thus rendered initial verification
checks useless, the programmer must continually verify all new form fields
and previous state (encapsulated in hidden form fields) to be sure the
desired constraints are met. This process of verification becomes tedious
to program especially if there are many forms required to produce a final
result.

   To tackle this problem I created CGI::EncryptForm, where by instead of
including state in hidden form fields verbatim, we use SHA1 encryption
algorithm to provide a satisfactory level of trust between the users
browser and the CGI script.

DESCRIPTION
===========

   An object is created with a secret key defined by the CGI script. The
objects encrypt() method is called with a perl data structure, which in the
context of CGI scripts would normally contain key/value pairs.  The
encrypt() method returns an encrypted string. The encrypted string is
stored in a hidden form field. The user fills in the form. The CGI script
processes the form, extracts the encrypted string from the hidden form
field, decrypts the string and returns the original data structure.
Further results from the form are added to the data structure, then it is
encrypted again and stored in the next form as a hidden field.  This
process continues until the CGI script has all the desired information and
is ready to process it. To process the results, the CGI script decrypts
the encrypted string from the last hidden form field, which contains the
*collective state* of all previous form input.

   Along the way, the users input was verified only once. The fact that
state was encrypted and therefore trusted, renders the process of
continually verifying all state for each form processed, unnecessary.

METHODS
=======

*new CGI::EncryptForm*([secret_key => $s [, usecharset => $a]])
     Create a new CGI::EncryptForm object. All of the paramaters are
     optional.  $s specifies the secret key to use during
     encryption/decryption. $a specifies whether to enable (1) or disable
     (0) the character set encoding/decoding of the encrypted/decrypted
     result. By default this is enabled.

encrypt($hashref)
     Encrypt the data structure and return an encrypted string. $hashref
     must be a reference to an associative array supported by the Storable
     module.  If called with no arguement, returns the previous encrypted
     string.

     Upon error, the method returns undef and sets error().

decrypt($encrypted_string)
     Decrypt the encrypted string and return a reference to an associative
     array.  $encrypted_string must be a scalar previously generated by
     encrypt().  If called with no arguement, returns the previous
     reference.

     Upon error, the method returns undef and sets error(). If the
     encrypted string is tampered with the decryption routine should fail
     with undef, but this is ultimately dependant on the strength of SHA1
     digests.

*secret_key*($secret)
     Sets the secret key for use during encryption/decryption. This method
     is analogues to the secret_key paramater when creating a
     CGI::EncryptForm object.  If called with no $secret it returns the
     current secret key or undef if undefined.

     Upon error, the method returns undef and sets error().

*usecharset*(1)
     Enables or disables the character set encoding/decoding of
     encrypted/decrypted strings. This method is analogues to the
     usecharset paramater when creating a CGI::EncryptForm object. By
     default usecharset is enabled (1) and should be ignored unless you
     use this module in non CGI programs. The encode/decode routine
     applies the default or user defined (*see charset()*) character set to
     encode/decode the encrypted string, before returning to the caller.

charset($arrayref)
     Sets the character set which will be used to encode/decode the
     encrypted/decrypted string. This method accepts a single array
     reference that must contain a character set from 0 to 255, where by
     each element must be 2 characters and UNIQUE. e.g.

          charset(qw[/aA aB aC aD ... /])

     If this method is not called with your own character set, a default
     character set will be used which produces suitable output to store the
     result of the encrypt() method in form fields, URL's and cookies.

     Upon error, the method returns undef and sets error().

error()
     Returns the last error as a scalar. You would normally read this if
     any method returns undef. error() is always cleared for each method
     that executes successfully.

EXAMPLE
=======

   This example illustrates the use of CGI::EncryptForm in combination with
CGI.pm to maintain stateful information in a multi-form CGI script.

     #!/usr/local/bin/perl

     use CGI::EncryptForm;
     use CGI;
     use vars qw($cgi $cfo);

     $cgi = new CGI();
     $cfo = new CGI::EncryptForm(secret_key => 'blah');

     print $cgi->header(), $cgi->start_html(), $cgi->start_form();

     if (defined $cgi->param('enc')) {
         form3();
     }
     elsif (defined $cgi->param('something')) {
         form2();
     }
     else {
         form1();
     }

     print $cgi->end_html(), $cgi->end_form();

     sub form1 {

     print "<h1>form1</h1>",
           "Type something and we will remember it: ",
           $cgi->textfield('something'), $cgi->submit();
       }

     sub form2 {

     print "<h1>form2</h1>",
           $cgi->hidden(-name=>'enc', value=>$cfo->encrypt({ $cgi->Vars })),
           "Now click here and I will tell you what you typed based on ",
           "the encrypted hidden form field, which you would normally ",
           "only see if you view the HTML source. For the sake of this ",
           "demonstration the encrypted field is included below.<p>",
           $cfo->encrypt(), "<p>",
           "Before proceeding with this form I suggest you take note of ",
           "what the encrypted field looks like, then click the back ",
           "button and resubmit the previous form with the same value ",
           "again. What you will notice is the encrypted field will ",
           "change. This is because the SHA encryption algorithm is ",
           "based on a secret key and a random key. In the module we ",
           "take care of generating a unique random key for each ",
           "invocation of the encryption routine, which is why a ",
           "distinct encrypted string is produced each time.",
           "<p>", $cgi->submit();
       }

     sub form3 {

     my $hashref = $cfo->decrypt($cgi->param('enc'));
     if (!defined($hashref)) {
       print $cfo->error();
       return;
     }
     print "<h1>form3</h1>",
           "Previously in the first form you typed:<p>", $hashref->{something},
           "<p>We reproduced this data by decrypting the hidden form ",
           "field called 'enc', which was passed to us from the previous ",
           "form. You may like to try and tamper with the hidden form ",
           "field in form2, to see if you can alter the result of the ",
           "data as it originally flows from form 1 to form 3. Good luck";
       }

NOTES
=====

   CGI::EncryptForm is not limited to form fields. The encrypted result
can be stored in cookies and URL's as well. Personally though, I
discourage this because your more likely to exceed size limitations with
various web browsers and servers.

BUGS
====

   None that I know of.

TODO
====

   None.

AUTHOR
======

   Copyright 1999, Peter Marelas.  All rights reserved.

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

   Bug reports and comments to maral@phase-one.com.au.

   Thanks to the authors of these fine perl modules Storable, Digest::SHA1
and Crypt::HCE_SHA.

SEE ALSO
========

   Storable, Digest::SHA1, Digest::HCE_SHA1


File: pm.info,  Node: CGI/Enurl,  Next: CGI/Explorer,  Prev: CGI/EncryptForm,  Up: Module List

module for URL-encoding strings and hashes
******************************************

NAME
====

   CGI::Enurl.pm - module for URL-encoding strings and hashes

   version 1.06

SYNOPSIS
========

     use CGI::Enurl;
     %hash = (name=>'Jenda Krynicky',address=>'Nerudova 1016');
     print "Location: http://$ENV{SERVER_NAME}/cgi-bin/do.pl?",enurl \%hash,"\n\n";

DESCRIPTION
===========

   This is a little module made for CGI scripting. It encodes the
parameters to be passed to a CGI. It does nothing more, so it's much
smaller and loads more quickly.

Functions
=========

enurl STRING
enurl ARRAY
enurl HASH
     Encodes the parameter. If the parameter is a single string it encodes
     it and returns the encoded form.

     If it is an array or a reference to an array it encodes all items and
     returns them joined by '&'.

     If it is a hash it encodes the values and return a querystring in form
     "key2=encoded_value1&key2=encoded_value2&...".

     !!! Please note that a hash in a list context returns a list of all
     keys and values. This means that if you call enurl(%hash) you will NOT
     get what you may thing you should. You HAVE to use enurl(\%hash) !!!

enURL STRING
     Encodes the parameter, this version doesn't encode '=' and '&'
     characters, so you should make sure they are not present in the data.

     Notice the difference :

          enurl 'a&b=f o o'   =>   'a%26b%3Df+o+o'
          enURL 'a&b=f o o'   =>   'a&b=f+o+o'

$Enurl::ParamSeparator
     You may specify another character to be used as the parameter
     separator.  Simply set this variable to the character (or string) you
     want to use.

     The default value is '&'

$Enurl::KeepUnencoded
     This variable contains the characters that should stay unencoded.
     Please keep in mind that the string will be interpolated into a regexp
     in a [^...] group!

     Any change of this variable will be ignored after the first call to
     enurl or enURL. (I'm using /o switch in the regexp.) So if you want to
     change the variable you should do it as soon as posible. You may do
     that even before you "use" the module!

     The default value is 'a-zA-Z 0-9_\\-@.='

EXAMPLE:
--------

     use CGI::Enurl;

     print "Location: http://www.somewhere.com/Scripts/search.pl?",
      enurl('something strange'),"\n\n";

   or

     use CGI::Enurl;

     print "Location: http://www.somewhere.com/Scripts/search.pl?",
      enurl('something strange','and other',666),"\n\n";

   or

     use CGI::Enurl;

     print "Location: http://www.somewhere.com/Scripts/myscript.pl?",
      enurl({fname => 'Jan',lname => 'Krynický',tel => '+420-2-9618 1234'},1),"\n\n";

   or

     use CGI::Enurl;

     print "Location: http://www.somewhere.com/Scripts/myscript.pl?",
      enURL('fname=Jan&lname=Krynický&tel=+420-2-9618 1234&1',"\n\n";

   or using the tricks of Interpolation.pm -
http://www.plover.com/~mjd/perl/Interpolation/manual.html

     use CGI::Enurl;
     use Interpolation URL => \&enurl;
     print "name=$URL{'Jann Linder, jr'}&address=$URL{'129 kjhlkjd st'}";

   or even

     use CGI::Enurl;
     use Interpolation enurl => sub {my %hash=split /$;/o,$_[0];enurl \%hash};
      # use other name instead of enurl if you like.

     print "script.pl?$enurl{name=>'Jenda Krynicky',address=>'Nerudova 1016'}\n";

     %hash = (name=>'Jenda Krynicky',address=>'Nerudova 1016');

     sub var {
      if (ref $_[0] eq 'HASH') {
        join $;, %{shift()}, @_;
      } else {
        join $;, @_;
      }
     }

     print "script.pl?$enurl{var %hash}\n";
     	 # the "var" is necessary !
         # without it you will get : "Odd number of elements in hash list at ... line 2."

     print "script.pl?$enurl{var %hash,age=>22}\n";

     # you may omit the "var" only if you enter the hash as a constant directly
     # into $enurl{...}.

   If you want to be cheeky you may use '$?{}' as the interpolator:

     use CGI::Enurl;
     use Interpolation '?' => sub {my %hash=split /$;/o,$_[0]; '?' . enurl \%hash};

     print "cript.pl$?{a=>5,b=>7,n=>'Jenda Krynicky'}\n";

   or

     use CGI::Enurl;
     use Interpolation '?' => sub {'?' . enURL $_[0]};

     print "cript.pl$?{'a=5&b=7&n=Jenda Krynicky'}\n";
     # # or
     # print qq{cript.pl$?{"a=5&b=7&n=$name"}\n};

   Please read the docs for enurl versus enURL so that you understand the
difference!

DISCLAIMER
----------

   The enurl_str function is taken from CGI.pm. (It's named 'escape'
there.) Thanks.

AUTHOR
------

   Jan Krynicky <Jenda@Krynicky.cz>

COPYRIGHT
---------

   Copyright (c) 1997 Jan Krynicky <Jenda@Krynicky.cz>. All rights
reserved.  This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.


File: pm.info,  Node: CGI/Explorer,  Next: CGI/FMBundle,  Prev: CGI/Enurl,  Up: Module List

A class to manage a tree of data, for use in CGI scripts
********************************************************

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.


File: pm.info,  Node: CGI/FMBundle,  Next: CGI/Fast,  Prev: CGI/Explorer,  Up: Module List

A bundle to install everything required for FormMagick
******************************************************

NAME
====

   Bundle::FormMagick - A bundle to install everything required for
FormMagick

SYNOPSIS
========

   `perl -MCPAN -e 'install Bundle::FormMagick''

CONTENTS
========

   Persistence::Object::Simple 0.47

   XML::Parser 2.30

   Text::Template 1.23

   CGI::Persistent

   Class::ParamParser

   Locale::Maketext 0.18

   Locale::Country 1.02

   Geography::States 1.3

   Time::ParseDate 00.01_03_01

   CGI::Persistent 0.21

   Business::CreditCard 0.21

DESCRIPTION
===========

   This bundle installs all the modules needed to run FormMagick, as well
as a bunch of modules required for the validation functions.

AUTHOR
======

   Kirrily "Skud" Robert (skud@infotrope.net)


File: pm.info,  Node: CGI/Fast,  Next: CGI/FastTemplate,  Prev: CGI/FMBundle,  Up: Module List

CGI Interface for Fast CGI
**************************

NAME
====

   CGI::Fast - CGI Interface for Fast CGI

SYNOPSIS
========

     use CGI::Fast qw(:standard);
     $COUNTER = 0;
     while (new CGI::Fast) {
     	print header;
     	print start_html("Fast CGI Rocks");
     	print
     	    h1("Fast CGI Rocks"),
     	    "Invocation number ",b($COUNTER++),
             " PID ",b($$),".",
     	    hr;
         print end_html;
     }

DESCRIPTION
===========

   CGI::Fast is a subclass of the CGI object created by CGI.pm.  It is
specialized to work well with the Open Market FastCGI standard, which
greatly speeds up CGI scripts by turning them into persistently running
server processes.  Scripts that perform time-consuming initialization
processes, such as loading large modules or opening persistent database
connections, will see large performance improvements.

OTHER PIECES OF THE PUZZLE
==========================

   In order to use CGI::Fast you'll need a FastCGI-enabled Web server.
Open Market's server is FastCGI-savvy.  There are also freely
redistributable FastCGI modules for NCSA httpd 1.5 and Apache.
FastCGI-enabling modules for Microsoft Internet Information Server and
Netscape Communications Server have been announced.

   In addition, you'll need a version of the Perl interpreter that has
been linked with the FastCGI I/O library.  Precompiled binaries are
available for several platforms, including DEC Alpha, HP-UX and
SPARC/Solaris, or you can rebuild Perl from source with patches provided
in the FastCGI developer's kit.  The FastCGI Perl interpreter can be used
in place of your normal Perl without ill consequences.

   You can find FastCGI modules for Apache and NCSA httpd, precompiled
Perl interpreters, and the FastCGI developer's kit all at URL:

     http://www.fastcgi.com/

WRITING FASTCGI PERL SCRIPTS
============================

   FastCGI scripts are persistent: one or more copies of the script are
started up when the server initializes, and stay around until the server
exits or they die a natural death.  After performing whatever one-time
initialization it needs, the script enters a loop waiting for incoming
connections, processing the request, and waiting some more.

   A typical FastCGI script will look like this:

     #!/usr/local/bin/perl    # must be a FastCGI version of perl!
     use CGI::Fast;
     &do_some_initialization();
     while ($q = new CGI::Fast) {
     	&process_request($q);
     }

   Each time there's a new request, CGI::Fast returns a CGI object to your
loop.  The rest of the time your script waits in the call to new().  When
the server requests that your script be terminated, new() will return
undef.  You can of course exit earlier if you choose.  A new version of the
script will be respawned to take its place (this may be necessary in order
to avoid Perl memory leaks in long-running scripts).

   CGI.pm's default CGI object mode also works.  Just modify the loop this
way:

     while (new CGI::Fast) {
     	&process_request;
     }

   Calls to header(), start_form(), etc. will all operate on the current
request.

INSTALLING FASTCGI SCRIPTS
==========================

   See the FastCGI developer's kit documentation for full details.  On the
Apache server, the following line must be added to srm.conf:

     AddType application/x-httpd-fcgi .fcgi

   FastCGI scripts must end in the extension .fcgi.  For each script you
install, you must add something like the following to srm.conf:

     AppClass /usr/etc/httpd/fcgi-bin/file_upload.fcgi -processes 2

   This instructs Apache to launch two copies of file_upload.fcgi at
startup time.

USING FASTCGI SCRIPTS AS CGI SCRIPTS
====================================

   Any script that works correctly as a FastCGI script will also work
correctly when installed as a vanilla CGI script.  However it will not see
any performance benefit.

CAVEATS
=======

   I haven't tested this very much.

AUTHOR INFORMATION
==================

   Copyright 1996-1998, Lincoln D. Stein.  All rights reserved.

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

   Address bug reports and comments to: lstein@cshl.org

BUGS
====

   This section intentionally left blank.

SEE ALSO
========

   *Note CGI/Carp: CGI/Carp,, *Note CGI: CGI,


File: pm.info,  Node: CGI/FastTemplate,  Next: CGI/Form,  Prev: CGI/Fast,  Up: Module List

Perl extension for managing templates, and performing variable interpolation.
*****************************************************************************

NAME
====

   CGI::FastTemplate - Perl extension for managing templates, and
performing variable interpolation.

SYNOPSIS
========

     use CGI::FastTemplate;

     $tpl = new CGI::FastTemplate();
     $tpl = new CGI::FastTemplate("/path/to/templates");

     CGI::FastTemplate->set_root("/path/to/templates");    ## all instances will use this path
     $tpl->set_root("/path/to/templates");                 ## this instance will use this path

     $tpl->define( main    => "main.tpl",
                   row     => "table_row.tpl",
                   all     => "table_all.tpl",
                   );

     $tpl->assign(TITLE => "I am the title.");

     my %defaults = (  FONT   => "<font size=+2 face=helvetica>",
                       EMAIL   => 'jmoore@sober.com',
                       );
     $tpl->assign(\%defaults);

     $tpl->parse(ROWS      => ".row");      ## the '.' appends to ROWS
     $tpl->parse(CONTENT   => ["row", "all"]);
     $tpl->parse(CONTENT   => "main");

     $tpl->print();            ## defaults to last parsed
     $tpl->print("CONTENT");   ## same as print() as "CONTENT" was last parsed

     $ref = $tpl->fetch("CONTENT");

DESCRIPTION
===========

What is a template?
-------------------

   A template is a text file with variables in it.  When a template is
parsed, the variables are interpolated to text.  (The text can be a few
bytes or a few hundred kilobytes.)  Here is a simple template with one
variable ('$NAME'):

     Hello $NAME.  How are you?

When are templates useful?
--------------------------

   Templates are very useful for CGI programming, because adding HTML to
your perl code clutters your code and forces you to do any HTML
modifications.  By putting all of your HTML in separate template files,
you can let a graphic or interface designer change the look of your
application without having to bug you, or let them muck around in your
perl code.

There are other templating modules on CPAN, what makes FastTemplate  different?
-------------------------------------------------------------------------------

   CGI::FastTemplate has the following attributes:

   Speed

   FastTemplate doesn't use eval, and parses with a single regular
expression.  It just does simple variable interpolation (i.e. there is no
logic that you can add to templates - you keep the logic in the code).
That's why it's has 'Fast' in it's name!

   Efficiency

   FastTemplate functions accept and return references whenever possible,
which saves needless copying of arguments (hashes, scalars, etc).

   *Flexibility*

   The API is robust and flexible, and allows you to build very complex
HTML documents or HTML interfaces.  It is 100% perl and works on Unix or
NT.  Also, it isn't restricted to building HTML documents - it could be
used to build any ascii based document (e.g. postscript, XML, email).

   The similar modules on CPAN are:

     Module          HTML::Template  (S/SA/SAMTREGAR/HTML-Template-0.04.tar.gz)
     Module          Taco::Template  (KWILLIAMS/Taco-0.04.tar.gz)
     Module          Text::BasicTemplate (D/DC/DCARRAWAY/Text-BasicTemplate-0.9.8.tar.gz)
     Module          Text::Template  (MJD/Text-Template-1.20.tar.gz)
     Module          HTML::Mason     (J/JS/JSWARTZ/HTML-Mason-0.5.1.tar.gz)

What are the steps to use FastTemplate?
---------------------------------------

   The main steps are:

     1. define
     2. assign
     3. parse
     4. print

   These are outlined in detail in CORE METHODS below.

CORE METHODS
============

define(HASH)
------------

   The method define() maps a template filename to a (usually shorter)
name. e.g.

     my $tpl = new FastTemplate();
     $tpl->define(   main   => "main.tpl",
                     footer   => "footer.tpl",
                     );

   This new name is the name that you will use to refer to the templates.
Filenames should not appear in any place other than a define().

   (Note: This is a required step!  This may seem like an annoying extra
step when you are dealing with a trivial example like the one above, but
when you are dealing with dozens of templates, it is very handy to refer
to templates with names that are indepandant of filenames.)

   TIP: Since define() does not actually load the templates, it is faster
and more legible to define all the templates with one call to define().

define_nofile(HASH)   alias: define_raw(HASH)
---------------------------------------------

   Sometimes it is desireable to not have to create a separate template
file for each template (though in the long run it is usually better to do
so).  The method define_nofile() allows you to do this.  For example, if
you were writing a news tool where you wanted to bold an item if it was
"new" you could do something like the following:

     my $tpl = new FastTemplate();

     $tpl->define_nofile(    new   => '<b>$ITEM_NAME</b> <BR>',
                             old   => '$ITEM_NAME <BR>');

     if ($new)
     {
         $tpl->parse($ITEM   => "new");
     }
     else
     {
         $tpl->parse($ITEM   => "old");
     }

   Of course, now you, the programmer has to update how new items are
displayed, whereas if it was in a template, you could offload that task to
someone else.

define_nofile(HASH REF)   alias: define_raw(HASH REF)
-----------------------------------------------------

   A more efficient way of passing your arguments than using a real hash.
Just pass in a hash reference instead of a real hash.

assign(HASH)
------------

   The method assign() assigns values for variables.  In order for a
variable in a template to be interpolated it must be assigned.  There are
two forms which have some important differences.  The simple form, is to
accept a hash and copy all the key/value pairs into a hash in FastTemplate.
There is only one hash in FastTemplate, so assigning a value for the same
key will overwrite that key.

     e.g.

     $tpl->assign(TITLE   => "king kong");
     $tpl->assign(TITLE   => "godzilla");    ## overwrites "king kong"

assign(HASH REF)
----------------

   A much more efficient way to pass in values is to pass in a hash
reference.  (This is particularly nice if you get back a hash or hash
reference from a database query.)  Passing a hash reference doesn't copy
the data, but simply keeps the reference in an array.  During parsing if
the value for a variable cannot be found in the main FastTemplate hash, it
starts to look through the array of hash references for the value.  As
soon as it finds the value it stops.  It is important to remember to
remove hash references when they are no longer needed.

     e.g.

     my %foo = ("TITLE" => "king kong");
     my %bar = ("TITLE" => "godzilla");

     $tpl->assign(\%foo);   ## TITLE resolves to "king kong"
     $tpl->clear_href(1);   ## remove last hash ref assignment (\%foo)
     $tpl->assign(\%bar);   ## TITLE resolves to "godzilla"

     $tpl->clear_href();    ## remove all hash ref assignments

     $tpl->assign(\%foo);   ## TITLE resolves to "king kong"
     $tpl->assign(\%bar);   ## TITLE _still_ resolves to "king kong"

parse(HASH)
-----------

   The parse function is the main function in FastTemplate.  It accepts a
hash, where the keys are the TARGET and the values are the SOURCE
templates.  There are three forms the hash can be in:

     $tpl->parse(MAIN => "main");                ## regular

     $tpl->parse(MAIN => ["table", "main"]);     ## compound

     $tpl->parse(MAIN => ".row");                ## append

   In the regular version, the template named "main" is loaded if it hasn't
been already, all the variables are interpolated, and the result is then
stored in FastTemplate as the value MAIN.  If the variable '$MAIN' shows
up in a later template, it will be interpolated to be the value of the
parsed "main" template.  This allows you to easily nest templates, which
brings us to the compound style.

   The compound style is designed to make it easier to nest templates.
The following are equivalent:

     $tpl->parse(MAIN => "table");
     $tpl->parse(MAIN => "main");

     ## is the same as:

     $tpl->parse(MAIN => ["table", "main"]);     ## this form saves function calls
                                                 ## (and makes your code cleaner)

   It is important to note that when you are using the compound form, each
template after the first, must contain the variable that you are parsing
the results into.  In the above example, 'main' must contain the variable
'$MAIN', as that is where the parsed results of 'table' is stored.  If
'main' does not contain the variable '$MAIN' then the parsed results of
'table' will be lost.

   The append style is a bit of a kludge, but it allows you to append the
parsed results to the target variable.  This is most useful when building
tables that have an dynamic number of rows - such as data from a database
query.

strict()
--------

   When strict() is on (it is on by default) all variables found during
template parsing that are unresolved have a warning printed to STDERR.
e.g.

     [CGI::FastTemplate] Warning: no value found for variable: SOME_VARIABLE

   Also, new as of version 1.04 the variables will be left in the output
document.  This was done for two reasons: to allow for parsing to be done
in stages (i.e. multiple passes), and to make it easier to identify
undefined variables since they appear in the parsed output.  If you have
been using an earlier version of FastTemplate and you want the old
behavior of replacing unknown variables with an empty string, see:
no_strict().

   Note: version 1.07 adds support for two styles of variables, so that the
following are equivalent: $VAR and ${VAR} However, when using strict(),
variables with curly brackets that are not resolved are outputted as plain
variables.  e.g. if ${VAR} has no value assigned to it, it would appear in
the output as $VAR.  This is a slight inconsistency - ideally the
unresolved variable would remain unchanged.

   Note: STDERR output should be captured and logged by the webserver so
you can just tail the error log to see the output.

     e.g.

     tail -f /etc/httpd/logs/error_log

no_strict()
-----------

   Turns off warning messages about unresolved template variables.  As of
version 1.04 a call to no_strict() is required to replace unknown
variables with an empty string.  By default, all instances of FastTemplate
behave as is strict() was called.  Also, no_strict() must be set for each
instance of CGI::FastTemplate. e.g.

     CGI::FastTemplate::no_strict;        ## no
     
     my $tpl = CGI::FastTemplate;
     $tpl->no_strict;                     ## yes

print(SCALAR)
-------------

   The method print() prints the contents of the named variable.  If no
variable is given, then it prints the last variable that was used in a
call to parse which I find is a reasonable default.

     e.g.

     $tpl->parse(MAIN => "main");
     $tpl->print();         ## prints value of MAIN
     $tpl->print("MAIN");   ## same

   This method is provided for convenience.

   If you need to print other than STDOUT (e.g. socket, file handle) see
fetch().

OTHER METHODS
=============

fetch(SCALAR)
-------------

   Returns a scalar reference to parsed data.

     $tpl->parse(CONTENT   => "main");
     my $content = $tpl->fetch("CONTENT");

     print $$content;        ## print to STDOUT
     print FILE $$content;   ## print to filehandle or pipe

clear()
-------

   Note: All of 'clear' functions are for use under mod_perl (or anywhere
where your scripts are persistant).  They generally aren't needed if you
are writing CGI scripts.

   Clears the internal hash that stores data passed from calls to assign()
and parse().

   Often clear() is at the end of a mod_perl script:

     $tpl->print();
     $tpl->clear();

clear(ARRAY)
------------

   With no arguments, all assigned or parsed variables are cleared, but if
passed an ARRAY of variable names, then only those variables will be
cleared.

     e.g.

     $tpl->assign(TITLE => "Welcome");
     $tpl->clear("TITLE");                 ## title is now empty

   Another way of achieving the same effect of clearnign variables is to
just assign an empty string.

     e.g.

     $tpl->assign(TITLE => '');           ## same as: $tpl->clear("TITLE");

clear_parse()
-------------

   See: clear()

clear_href(NUMBER)
------------------

   Removes a given number of hash references from the list of hash refs
that is built using:

     $tpl->assign(HASH REF);

   If called with no arguments, it removes all hash references from the
array.  This is often used for database queries where each row from the
query is a hash or hash reference.

   e.g.

   while($hash_row = $sth->fetchrow_hashref)     {
$tpl->assign($hash_row);         $tpl->parse(ROW => ".row");
$tpl->clear_href(1);     }

clear_define()
--------------

   Clears the internal hash that stores data passed to:

     $tpl->define();

   Note: The hash that holds the loaded templates is not touched with this
method.  See: clear_tpl

clear_tpl() clear_tpl(NAME)
---------------------------

   The first time a template is used, it is loaded and stored in a hash in
memory.  clear_tpl() removes all the templates being held in memory.
clear_tpl(NAME) only removes the one with NAME.  This is generally not
required for normal CGI programming, but if you have long running scripts
(e.g. mod_perl) and have very large templates that a re infrequently used
gives you some control over how memory is being used.

clear_all()
-----------

   Cleans the module of any data, except for the ROOT directory.
Equivalent to:

     $tpl->clear_define();
     $tpl->clear_href();
     $tpl->clear_tpl();
     $tpl->clear_parse();

Variables
---------

   A variable is defined as:

     $[A-Z0-9][A-Z0-9_]+

   This means, that a variable must begin with a dollar sign '$'.  The
second character must be an uppercase letter or digit 'A-Z0-9'.  Remaining
characters can include an underscore.

   As of version 1.07 variables can also be delimited by curly brackets.

     ${[A-Z0-9][A-Z0-9_]+}

   For example, the following are valid variables:

     $FOO
     $F123F
     $TOP_OF_PAGE
     ${NEW_STYLE}

Variable Interpolation (Template Parsing)
-----------------------------------------

   When the a template is being scanned for variables, pattern matching is
greedy. (For more info on "greediness" of regexps see *Note Perlre:
(perl.info)perlre,.)  This is important, because if there are valid
variable characters after your variable, FastTemplate will consider them
to be part of the variable.  As of version 1.07 you can use curly brackets
as delimiters for your variable names.  e.g. ${VARIABLE}  You do not need
to use curly brackets if the character immediately after your variable
name is not an uppercase letter, digit or underscore.  ['A-Z0-9_']

   If a variable cannot be resolved to a value then there are two
possibilities.  If strict() has been called (it is on by default) then the
variable remains and a warning is printed to STDERR.   If no_strict() has
been called then the variables is converted to an empty string ["].

   See `strict()' in this node and `no_strict()' in this node for more
info.

   Some examples will make this clearer.

     Assume:

     $FOO = "foo";
     $BAR = "bar";
     $ONE = "1";
     $TWO = "2";
     $UND = "_";
     
     Variable        Interpolated/Parsed
     ------------------------------------------------
     $FOO            foo
     $FOO-$BAR       foo-bar
     $ONE_$TWO       2             ## $ONE_ is undefined!
     $ONE_$TWO       $ONE_2        ## assume: strict()
     $ONE$UND$TWO    1_2           ## kludge!
     ${ONE}_$TWO     1_2           ## much better
     $$FOO           $foo
     $25,000         $25,000

FULL EXAMPLE
------------

   This example will build an HTML page that will consist of a table.  The
table will have 3 numbered rows.  The first step is to decide what
templates we need.  In order to make it easy for the table to change to a
different number of rows, we will have a template for the rows of the
table, another for the table, and a third for the head/body part of the
HTML page.

   Below are the templates. (Pretend each one is in a separate file.)

     <!-- NAME: main.tpl -->
     <html>
     <head><title>$TITLE</title>
     </head>
     <body>
     $MAIN
     </body>
     </html>
     <!-- END: main.tpl -->
     
     
     <!-- NAME: table.tpl -->
     <table>
     $ROWS
     </table>
     <!-- END: table.tpl -->
     
     
     <!-- NAME: row.tpl -->
     <tr>
     <td>$NUMBER</td>
     <td>$BIG_NUMBER</td>
     </tr>
     <!-- END: row.tpl -->

   Now we can start coding...

     ## START ##

     use CGI::FastTemplate;
     my $tpl = new CGI::FastTemplate("/path/to/template/files");
     
     $tpl->define(     main    => "main.tpl",
                       table   => "table.tpl",
                       row     => "row.tpl",
                       );

     $tpl->assign(TITLE => "FastTemplate Test");

     for $n (1..3)
     {
           $tpl->assign(   NUMBER      => $n,
           BIG_NUMBER   => $n*10);
           $tpl->parse(ROWS   => ".row");
     }

     $tpl->parse(MAIN => ["table", "main"]);
     $tpl->print();

     ## END ##
     
     When run it returns:

     <!-- NAME: main.tpl -->
     <html>
     <head><title>FastTemplate Test</title>
     </head>
     <body>
     <!-- NAME: table.tpl -->
     <table>
     <!-- NAME: row.tpl -->
     <tr>
     <td>1</td>
     <td>10</td>
     </tr>
     <!-- END: row.tpl -->
     <!-- NAME: row.tpl -->
     <tr>
     <td>2</td>
     <td>20</td>
     </tr>
     <!-- END: row.tpl -->
     <!-- NAME: row.tpl -->
     <tr>
     <td>3</td>
     <td>30</td>
     </tr>
     <!-- END: row.tpl -->
     
     </table>
     <!-- END: table.tpl -->

     </body>
     </html>
     <!-- END: main.tpl -->

   If you're thinking you could have done the same thing in a few lines of
plain perl, well yes you probably could.  But, how would a graphic
designer tweak the resulting HTML?  How would you have a designer editing
the HTML while you're editing another part of the code?  How would you
save the output to a file, or pipe it to another application (e.g.
sendmail)?  How would you make your application multi-lingual?  How would
you build an application that has options for high graphics, or text-only?
FastTemplate really starts to shine when you are building mid to large
scale web applications, simply because it begins to separate the
application's generic logic from the specific implementation.

COPYRIGHT
=========

     Copyright (c) 1998-99 Jason Moore <jmoore@sober.com>.  All rights
     reserved.

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

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     Artistic License for more details.

AUTHOR
======

   Jason Moore <jmoore@sober.com>

SEE ALSO
========

   mod_perl(1).


File: pm.info,  Node: CGI/Form,  Next: CGI/FormMagick,  Prev: CGI/FastTemplate,  Up: Module List

Build Smart HTML Forms on Top of the CGI:: Modules
**************************************************

NAME
====

   CGI::Form - Build Smart HTML Forms on Top of the CGI:: Modules

ABSTRACT
========

   This perl library uses perl5 objects to make it easy to create Web
fill-out forms and parse their contents.  This package defines CGI
objects, entities that contain the values of the current query string and
other state variables.  Using a CGI object's methods, you can examine
keywords and parameters passed to your script, and create forms whose
initial values are taken from the current query (thereby preserving state
information).

INSTALLATION:
=============

   To use this package, install it in your perl library path (usually
/usr/local/lib/perl5/ and add the following to your perl CGI script:

     Use CGI::Form;

DESCRIPTION
===========

CREATING A NEW FORM OBJECT AND PROCESSING PARAMETERS:
-----------------------------------------------------

     $query = new CGI::Form;

   This will parse the input (from both POST and GET methods) and store it
into a perl5 object called $query.  This method is inherited from *Note
CGI/Request: CGI/Request,.  See its manpage for details.  Similarly,
CGI::Form uses CGI::Request to get and set named query parameters, e.g.

     @values = $query->param('foo');

     -and-

     $query->param('foo','an','array','of','values');
     or whatever!

CALLING CGI::Form FUNCTIONS THAT TAKE MULTIPLE ARGUMENTS
--------------------------------------------------------

   In versions of Form.pm prior to 2.8, it could get difficult to remember
the proper order of arguments in CGI function calls that accepted five or
six different arguments.  As of 2.8, there's a better way to pass
arguments to the various CGI functions.  In this style, you pass a series
of name=>argument pairs, like this:

     $field = $query->radio_group(-name=>'OS',
                                  -values=>[Unix,Windows,Macintosh],
                                  -default=>'Unix');

   The advantages of this style are that you don't have to remember the
exact order of the arguments, and if you leave out a parameter, in most
cases it will default to some reasonable value.  If you provide a
parameter that the method doesn't recognize, it will usually do something
useful with it, such as incorporating it into the HTML form tag.  For
example if Netscape decides next week to add a new JUSTIFICATION parameter
to the text field tags, you can start using the feature without waiting
for a new version of CGI.pm:

     $field = $query->textfield(-name=>'State',
                                -default=>'gaseous',
                                -justification=>'RIGHT');

   This will result in an HTML tag that looks like this:

     <INPUT TYPE="textfield" NAME="State" VALUE="gaseous"
                    JUSTIFICATION="RIGHT">

   Parameter names are case insensitive: you can use -name, or -Name or
-NAME.  You don't have to use the hyphen if you don't want to.  After
creating a CGI object, call the *use_named_parameters()* method with a
nonzero value.  This will tell CGI.pm that you intend to use named
parameters exclusively:

     $query = new CGI;
     $query->use_named_parameters(1);
     $field = $query->radio_group('name'=>'OS',
                                  'values'=>['Unix','Windows','Macintosh'],
                                  'default'=>'Unix');

   Actually, CGI.pm only looks for a hyphen in the first parameter.  So
you can leave it off subsequent parameters if you like.  Something to be
wary of is the potential that a string constant like "values" will collide
with a keyword (and in fact it does!) While Perl usually figures out when
you're referring to a function and when you're referring to a string, you
probably should put quotation marks around all string constants just to
play it safe.

CREATING A SELF-REFERENCING URL THAT PRESERVES STATE INFORMATION:
-----------------------------------------------------------------

     $myself = $query->self_url
     print "<A HREF=$myself>I'm talking to myself.</A>

   self_url() will return a URL, that, when selected, will reinvoke this
script with all its state information intact.  This is most useful when
you want to jump around within the document using internal anchors but you
don't want to disrupt the current contents of the form(s).  Something like
this will do the trick.

     $myself = $query->self_url
     print "<A HREF=$myself#table1>See table 1</A>
     print "<A HREF=$myself#table2>See table 2</A>
     print "<A HREF=$myself#yourself>See for yourself</A>

   This method is actually defined in *Note CGI/Base: CGI/Base,, but is
passed through here for compatability with CGI.pm

CREATING THE HTTP HEADER:
-------------------------

     print $query->header;

     -or-

     print $query->header('image/gif');

   header() returns the Content-type: header.  you can provide your own
MIME type if you choose, otherwise it defaults to text/html.

   This method is provided for compatability with CGI.pm *only*.  It is
much better to use the SendHeaders() method of *Note CGI/Base: CGI/Base,.

   NOTE: This is a temporary method that will be replaced by the
CGI::Response module as soon as it is released.

GENERATING A REDIRECTION INSTRUCTION
------------------------------------

     print $query->redirect('http://somewhere.else/in/movie/land');

   redirect the browser elsewhere.  If you use redirection like this, you
should not print out a header as well.

   This method is provided for compatability with CGI.pm *only*.  New
scripts should use CGI::Base's redirect() method instead.

CREATING THE HTML HEADER:
-------------------------

     print $query->start_html(-title=>'Secrets of the Pyramids',
                              -author=>'fred@capricorn.org',
                              -base=>'true',
                              -BGCOLOR=>"#00A0A0"');

     -or-

     print $query->start_html('Secrets of the Pyramids',
                              'fred@capricorn.org','true',
                              'BGCOLOR="#00A0A0"');

   This will return a canned HTML header and the opening <BODY> tag.  All
parameters are optional.   In the named parameter form, recognized
parameters are -title, -author and -base (see below for the explanation).
Any additional parameters you provide, such as the Netscape unofficial
BGCOLOR attribute, are added to the <BODY> tag.

   Positional parameters are as follows:

Parameters:

     The title


     The author's e-mail address (will create a <LINK REV="MADE"> tag if
     present


     A 'true' flag if you want to include a <BASE> tag in the header.  This
     helps resolve relative addresses to absolute ones when the document
     is moved, but makes the document hierarchy non-portable.  Use with
     care!

5, 6...
     Any other parameters you want to include in the <BODY> tag.  This is
     a good place to put Netscape extensions, such as colors and wallpaper
     patterns.

ENDING THE HTML DOCUMENT:
-------------------------

     print $query->end_html

   This ends an HTML document by printing the </BODY></HTML> tags.

CREATING FORMS:
===============

   *General note*  The various form-creating methods all return strings to
the caller, containing the tag or tags that will create the requested form
element.  You are responsible for actually printing out these strings.
It's set up this way so that you can place formatting tags around the form
elements.

   *Another note* The default values that you specify for the forms are
only used the first time the script is invoked.  If there are already
values present in the query string, they are used, even if blank.  If you
want to change the value of a field from its previous value, call the
param() method to set it.

   *Yet another note* By default, the text and labels of form elements are
escaped according to HTML rules.  This means that you can safely use
"<CLICK ME>" as the label for a button.  However, it also interferes with
your ability to incorporate special HTML character sequences, such as
&Aacute;, into your fields.  If you wish to turn off automatic escaping,
call the autoEscape() method with a false value immediately after creating
the CGI object:

     $query = new CGI::Form;
     $query->autoEscape(undef);

CREATING AN ISINDEX TAG
-----------------------

     print $query->isindex($action);

   Prints out an <ISINDEX> tag.  Not very exciting.  The optional
parameter specifies an ACTION="<URL>" attribute.

STARTING AND ENDING A FORM
--------------------------

     print $query->startform($method,$action,$encoding);
       <... various form stuff ...>
     print $query->endform;

   startform() will return a <FORM> tag with the optional method, action
and form encoding that you specify.  The defaults are:

   method: POST     action: this script     encoding:
application/x-www-form-urlencoded

   The encoding method tells the browser how to package the various fields
of the form before sending the form to the server.  Two values are
possible:

*application/x-www-form-urlencoded*
     This is the older type of encoding used by all browsers prior to
     Netscape 2.0.  It is compatible with many CGI scripts and is suitable
     for short fields containing text data.

*multipart/form-data*
     This is the newer type of encoding introduced by Netscape 2.0.  It is
     suitable for forms that contain very large fields or that are
     intended for transferring binary data.  Most importantly, it enables
     the "file upload" feature of Netscape 2.0 forms.

     Forms that use this type of encoding are not easily interpreted by
     CGI scripts unless they use CGI.pm or another library designed to
     handle them.

   For your convenience, Form.pm defines two subroutines that contain the
values of the two alternative encodings:

     use CGI::Form(URL_ENCODED,MULTIPART);

   For compatability, the startform() method uses the older form of
encoding by default.  If you want to use the newer form of encoding by
default, you can call *start_multipart_form()* instead of *startform()*.

   endform() returns a </FORM> tag.

CREATING A TEXT FIELD
---------------------

     print $query->textfield(-name=>'field_name',
     	                    -default=>'starting value',
     	                    -size=>50,
     	                    -maxlength=>80);
     	-or-

     print $query->textfield('field_name','starting value',50,80);

   textfield() will return a text input field.

Parameters

     The first parameter is the required name for the field (-name).


     The optional second parameter is the default starting value for the
     field contents (-default).


     The optional third parameter is the size of the field in
     characters (-size).


     The optional fourth parameter is the maximum number of characters the
          field will accept (-maxlength).

   As with all these methods, the field will be initialized with its
previous contents from earlier invocations of the script.  When the form
is processed, the value of the text field can be retrieved with:

     $value = $query->param('foo');

   If you want to reset it from its initial value after the script has been
called once, you can do so like this:

     $query->param('foo',"I'm taking over this value!");

CREATING A BIG TEXT FIELD
-------------------------

     print $query->textarea(-name=>'foo',
     	 		  -default=>'starting value',
     	                  -rows=>10,
     	                  -columns=>50);

     -or

     print $query->textarea('foo','starting value',10,50);

   textarea() is just like textfield, but it allows you to specify rows
and columns for a multiline text entry box.  You can provide a starting
value for the field, which can be long and contain multiple lines.

CREATING A PASSWORD FIELD
-------------------------

     print $query->password_field(-name=>'secret',
     				-value=>'starting value',
     				-size=>50,
     				-maxlength=>80);
     	-or-

     print $query->password_field('secret','starting value',50,80);

   password_field() is identical to textfield(), except that its contents
will be starred out on the web page.

CREATING A FILE UPLOAD FIELD
----------------------------

     print $query->filefield(-name=>'uploaded_file',
     	                    -default=>'starting value',
     	                    -size=>50,
     	 		    -maxlength=>80);
     	-or-

     print $query->filefield('uploaded_file','starting value',50,80);

   filefield() will return a file upload field for Netscape 2.0 browsers.
In order to take full advantage of this *you must use the new multipart
encoding scheme* for the form.  You can do this either by calling
*startform()* with an encoding type of *$CGI::MULTIPART*, or by calling
the new method *start_multipart_form()* instead of vanilla *startform()*.

Parameters

     The first parameter is the required name for the field (-name).


     The optional second parameter is the starting value for the field
     contents to be used as the default file name (-default).

     The beta2 version of Netscape 2.0 currently doesn't pay any attention
     to this field, and so the starting value will always be blank.  Worse,
     the field loses its "sticky" behavior and forgets its previous
     contents.  The starting value field is called for in the HTML
     specification, however, and possibly later versions of Netscape will
     honor it.


     The optional third parameter is the size of the field in characters
     (-size).


     The optional fourth parameter is the maximum number of characters the
     field will accept (-maxlength).

   When the form is processed, you can retrieve the entered filename by
calling param().

     $filename = $query->param('uploaded_file');

   In Netscape Beta 1, the filename that gets returned is the full local
filename on the *remote user's* machine.  If the remote user is on a Unix
machine, the filename will follow Unix conventions:

     /path/to/the/file

   On an MS-DOS/Windows machine, the filename will follow DOS conventions:

     C:\PATH\TO\THE\FILE.MSW

   On a Macintosh machine, the filename will follow Mac conventions:

     HD 40:Desktop Folder:Sort Through:Reminders

   In Netscape Beta 2, only the last part of the file path (the filename
itself) is returned.  I don't know what the release behavior will be.

   The filename returned is also a file handle.  You can read the contents
of the file using standard Perl file reading calls:

     # Read a text file and print it out
     while (<$filename>) {
        print;
             }

     # Copy a binary file to somewhere safe
     open (OUTFILE,">>/usr/local/web/users/feedback");
     	while ($bytesread=read($filename,$buffer,1024)) {
     	   print OUTFILE $buffer;
     }

CREATING A POPUP MENU
---------------------

     print $query->popup_menu('menu_name',
                              ['eenie','meenie','minie'],
                              'meenie');

     -or-

     %labels = ('eenie'=>'your first choice',
                'meenie'=>'your second choice',
                'minie'=>'your third choice');
     print $query->popup_menu('menu_name',
                              ['eenie','meenie','minie'],
                              'meenie',\%labels);

     -or (named parameter style)-

     print $query->popup_menu(-name=>'menu_name',
     			    -values=>['eenie','meenie','minie'],
     	                    -default=>'meenie',
     	                    -labels=>\%labels);

   popup_menu() creates a menu.

  1. The required first argument is the menu's name (-name).

  2. The required second argument (-values) is an array reference
     containing the list of menu items in the menu.  You can pass the
     method an anonymous array, as shown in the example, or a reference to
     a named array, such as "\@foo".

  3. The optional third parameter (-default) is the name of the default
     menu choice.  If not specified, the first item will be the default.
     The values of the previous choice will be maintained across queries.

  4. The optional fourth parameter (-labels) is provided for people who
     want to use different values for the user-visible label inside the
     popup menu nd the value returned to your script.  It's a pointer to an
     associative array relating menu values to user-visible labels.  If you
     leave this parameter blank, the menu values will be displayed by
     default.  (You can also leave a label undefined if you want to).

        When the form is processed, the selected value of the popup menu
can be retrieved using:

     $popup_menu_value = $query->param('menu_name');

CREATING A SCROLLING LIST
-------------------------

     print $query->scrolling_list('list_name',
                                  ['eenie','meenie','minie','moe'],
                                  ['eenie','moe'],5,'true');
        -or-

     print $query->scrolling_list('list_name',
                                  ['eenie','meenie','minie','moe'],
                                  ['eenie','moe'],5,'true',
                                  \%labels);

     -or-

     print $query->scrolling_list(-name=>'list_name',
                                  -values=>['eenie','meenie','minie','moe'],
                                  -default=>['eenie','moe'],
     	                        -size=>5,
     	                        -multiple=>'true',
                                  -labels=>\%labels);

   scrolling_list() creates a scrolling list.

Parameters:

     The first and second arguments are the list name (-name) and values
     (-values).  As in the popup menu, the second argument should be an
     array reference.


     The optional third argument (-default) can be either a reference to a
     list containing the values to be selected by default, or can be a
     single value to select.  If this argument is missing or undefined,
     then nothing is selected when the list first appears.  In the named
     parameter version, you can use the synonym "-defaults" for this
     parameter.


     The optional fourth argument is the size of the list (-size).


     The optional fifth argument can be set to true to allow multiple
     simultaneous selections (-multiple).  Otherwise only one selection
     will be allowed at a time.


     The optional sixth argument is a pointer to an associative array
     containing long user-visible labels for the list items (-labels).  If
     not provided, the values will be displayed.

     When this form is procesed, all selected list items will be returned
     as a list under the parameter name 'list_name'.  The values of the
     selected items can be retrieved with:

          @selected = $query->param('list_name');

CREATING A GROUP OF RELATED CHECKBOXES
--------------------------------------

     print $query->checkbox_group(-name=>'group_name',
                                  -values=>['eenie','meenie','minie','moe'],
                                  -default=>['eenie','moe'],
     	                        -linebreak=>'true',
     	                        -labels=>\%labels);

     print $query->checkbox_group('group_name',
                                  ['eenie','meenie','minie','moe'],
                                  ['eenie','moe'],'true',\%labels);

     HTML3-COMPATIBLE BROWSERS ONLY:

     print $query->checkbox_group(-name=>'group_name',
                                  -values=>['eenie','meenie','minie','moe'],
     	                        -rows=2,-columns=>2);

   checkbox_group() creates a list of checkboxes that are related by the
same name.

Parameters:

     The first and second arguments are the checkbox name and values,
     respectively (-name and -values).  As in the popup menu, the second
     argument should be an array reference.  These values are used for the
     user-readable labels printed next to the checkboxes as well as for the
     values passed to your script in the query string.


     The optional third argument (-default) can be either a reference to a
     list containing the values to be checked by default, or can be a
     single value to checked.  If this argument is missing or undefined,
     then nothing is selected when the list first appears.


     The optional fourth argument (-linebreak) can be set to true to place
     line breaks between the checkboxes so that they appear as a vertical
     list.  Otherwise, they will be strung together on a horizontal line.


     The optional fifth argument is a pointer to an associative array
     relating the checkbox values to the user-visible labels that will will
     be printed next to them (-labels).  If not provided, the values will
     be used as the default.


     *HTML3-compatible browsers* (such as Netscape) can take advantage of
     the optional parameters *-rows*, and *-columns*.  These parameters
     cause checkbox_group() to return an HTML3 compatible table containing
     the checkbox group formatted with the specified number of rows and
     columns.  You can provide just the -columns parameter if you wish;
     checkbox_group will calculate the correct number of rows for you.

     To include row and column headings in the returned table, you can use
     the *-rowheader* and *-colheader* parameters.  Both of these accept a
     pointer to an array of headings to use.  The headings are just
     decorative.  They don't reorganize the interpetation of the
     checkboxes - they're still a single named unit.

   When the form is processed, all checked boxes will be returned as a
list under the parameter name 'group_name'.  The values of the "on"
checkboxes can be retrieved with:

     @turned_on = $query->param('group_name');

CREATING A STANDALONE CHECKBOX
------------------------------

     print $query->checkbox(-name=>'checkbox_name',
     			   -checked=>'checked',
     		           -value=>'ON',
     		           -label=>'CLICK ME');

     -or-

     print $query->checkbox('checkbox_name','checked','ON','CLICK ME');

   checkbox() is used to create an isolated checkbox that isn't logically
related to any others.

Parameters:

     The first parameter is the required name for the checkbox (-name).  It
     will also be used for the user-readable label printed next to the
     checkbox.


     The optional second parameter (-checked) specifies that the checkbox
     is turned on by default.  Synonyms are -selected and -on.


     The optional third parameter (-value) specifies the value of the
     checkbox when it is checked.  If not provided, the word "on" is
     assumed.


     The optional fourth parameter (-label) is the user-readable label to
     be attached to the checkbox.  If not provided, the checkbox name is
     used.

   The value of the checkbox can be retrieved using:

     $turned_on = $query->param('checkbox_name');

CREATING A RADIO BUTTON GROUP
-----------------------------

     print $query->radio_group(-name=>'group_name',
     			     -values=>['eenie','meenie','minie'],
                               -default=>'meenie',
     			     -linebreak=>'true',
     			     -labels=>\%labels);

     -or-

     print $query->radio_group('group_name',['eenie','meenie','minie'],
                                            'meenie','true',\%labels);

     HTML3-COMPATIBLE BROWSERS ONLY:

     print $query->checkbox_group(-name=>'group_name',
                                  -values=>['eenie','meenie','minie','moe'],
     	                        -rows=2,-columns=>2);

   radio_group() creates a set of logically-related radio buttons (turning
one member of the group on turns the others off)

Parameters:

     The first argument is the name of the group and is required (-name).


     The second argument (-values) is the list of values for the radio
     buttons.  The values and the labels that appear on the page are
     identical.  Pass an array reference in the second argument, either
     using an anonymous array, as shown, or by referencing a named array as
     in "\@foo".


     The optional third parameter (-default) is the name of the default
     button to turn on. If not specified, the first item will be the
     default.  You can provide a nonexistent button name, such as "-" to
     start up with no buttons selected.


     The optional fourth parameter (-linebreak) can be set to 'true' to put
     line breaks between the buttons, creating a vertical list.


     The optional fifth parameter (-labels) is a pointer to an associative
     array relating the radio button values to user-visible labels to be
     used in the display.  If not provided, the values themselves are
     displayed.


     *HTML3-compatible browsers* (such as Netscape) can take advantage of
     the optional parameters *-rows*, and *-columns*.  These parameters
     cause radio_group() to return an HTML3 compatible table containing
     the radio group formatted with the specified number of rows and
     columns.  You can provide just the -columns parameter if you wish;
     radio_group will calculate the correct number of rows for you.

     To include row and column headings in the returned table, you can use
     the *-rowheader* and *-colheader* parameters.  Both of these accept a
     pointer to an array of headings to use.  The headings are just
     decorative.  They don't reorganize the interpetation of the radio
     buttons - they're still a single named unit.

   When the form is processed, the selected radio button can be retrieved
using:

     $which_radio_button = $query->param('group_name');

CREATING A SUBMIT BUTTON
------------------------

     print $query->submit(-name=>'button_name',
     		        -value=>'value');

     -or-

     print $query->submit('button_name','value');

   submit() will create the query submission button.  Every form should
have one of these.

Parameters:

     The first argument (-name) is optional.  You can give the button a
     name if you have several submission buttons in your form and you want
     to distinguish between them.  The name will also be used as the
     user-visible label.  Be aware that a few older browsers don't deal
     with this correctly and never send back a value from a button.


     The second argument (-value) is also optional.  This gives the button
     a value that will be passed to your script in the query string.

   You can figure out which button was pressed by using different values
for each one:

     $which_one = $query->param('button_name');

CREATING A RESET BUTTON
-----------------------

     print $query->reset

   reset() creates the "reset" button.  Note that it restores the form to
its value from the last time the script was called, NOT necessarily to the
defaults.

CREATING A DEFAULT BUTTON
-------------------------

     print $query->defaults('button_label')

   defaults() creates a button that, when invoked, will cause the form to
be completely reset to its defaults, wiping out all the changes the user
ever made.

CREATING A HIDDEN FIELD
-----------------------

     print $query->hidden(-name=>'hidden_name',
                          -default=>['value1','value2'...]);

     -or-

     print $query->hidden('hidden_name','value1','value2'...);

   hidden() produces a text field that can't be seen by the user.  It is
useful for passing state variable information from one invocation of the
script to the next.

Parameters:

     The first argument is required and specifies the name of this field
     (-name).


     The second argument is also required and specifies its value
     (-default).  In the named parameter style of calling, you can provide
     a single value here or a reference to a whole list

   Fetch the value of a hidden field this way:

     $hidden_value = $query->param('hidden_name');

   Note, that just like all the other form elements, the value of a hidden
field is "sticky".  If you want to replace a hidden field with some other
values after the script has been called once you'll have to do it manually:

     $query->param('hidden_name','new','values','here');

CREATING A CLICKABLE IMAGE BUTTON
---------------------------------

     print $query->image_button(-name=>'button_name',
     			        -src=>'/source/URL',
     			        -align=>'MIDDLE');

     -or-

     print $query->image_button('button_name','/source/URL','MIDDLE');

   image_button() produces a clickable image.  When it's clicked on the
position of the click is returned to your script as "button_name.x" and
"button_name.y", where "button_name" is the name you've assigned to it.

Parameters:

     The first argument (-name) is required and specifies the name of this
     field.


     The second argument (-src) is also required and specifies the URL

The third option (-align, optional) is an alignment type, and may be TOP, BOTTOM or MIDDLE
   Fetch the value of the button this way:      $x =
$query->param('button_name.x');      $y = $query->param('button_name.y');

DEBUGGING:
==========

   If you are running the script from the command line or in the perl
debugger, you can pass the script a list of keywords or parameter=value
pairs on the command line or from standard input (you don't have to worry
about tricking your script into reading from environment variables).  You
can pass keywords like this:

     your_script.pl keyword1 keyword2 keyword3

   or this:

     your_script.pl keyword1+keyword2+keyword3

   or this:

     your_script.pl name1=value1 name2=value2

   or this:

     your_script.pl name1=value1&name2=value2

   or even as newline-delimited parameters on standard input.

   When debugging, you can use quotes and backslashes to escape characters
in the familiar shell manner, letting you place spaces and other funny
characters in your parameter=value pairs:

     your_script.pl name1='I am a long value' name2=two\ words

DUMPING OUT ALL THE NAME/VALUE PAIRS
------------------------------------

   The dump() method produces a string consisting of all the query's
name/value pairs formatted nicely as a nested list.  This is useful for
debugging purposes:

     print $query->dump

   Produces something that looks like:

     <UL>
     <LI>name1
         <UL>
         <LI>value1
         <LI>value2
         </UL>
     <LI>name2
         <UL>
         <LI>value1
         </UL>
     </UL>

   You can pass a value of 'true' to dump() in order to get it to print
the results out as plain text, suitable for incorporating into a <PRE>
section.

FETCHING ENVIRONMENT VARIABLES
==============================

   All the environment variables, such as REMOTE_HOST and HTTP_REFERER,
are available through the CGI::Base object.  You can get at these
variables using with the cgi() method (inherited from CGI::Request):

     $query->cgi->var('REMOTE_HOST');

AUTHOR INFORMATION
==================

   This code is copyright 1995 by Lincoln Stein and the Whitehead
Institute for Biomedical Research.  It may be used and modified freely.  I
request, but do not require, that this credit appear in the code.

   Address bug reports and comments to: lstein@genome.wi.mit.edu

A COMPLETE EXAMPLE OF A SIMPLE FORM-BASED SCRIPT
================================================

     #!/usr/local/bin/perl
     
             use CGI::Form;
     
             $query = new CGI::Form;

     print $query->header;
     print $query->start_html("Example CGI.pm Form");
     print "<H1> Example CGI.pm Form</H1>\n";
     &print_prompt($query);
     &do_work($query);
     	&print_tail;
     print $query->end_html;
     
     sub print_prompt {
          	   my($query) = @_;
     
          	   print $query->startform;
          	   print "<EM>What's your name?</EM><BR>";
          	   print $query->textfield('name');
          	   print $query->checkbox('Not my real name');
     
          	   print "<P><EM>Where can you find English Sparrows?</EM><BR>";
          	   print $query->checkbox_group('Sparrow locations',
     			 [England,France,Spain,Asia,Hoboken],
     			 [England,Asia]);
     
          	   print "<P><EM>How far can they fly?</EM><BR>",
                 	$query->radio_group('how far',
     	       ['10 ft','1 mile','10 miles','real far'],
     	       '1 mile');
     
          	   print "<P><EM>What's your favorite color?</EM>  ";
          	   print $query->popup_menu('Color',['black','brown','red','yellow'],'red');
     
          	   print $query->hidden('Reference','Monty Python and the Holy Grail');
     
          	   print "<P><EM>What have you got there?</EM>  ";
          	   print $query->scrolling_list('possessions',
     		 ['A Coconut','A Grail','An Icon',
     		  'A Sword','A Ticket'],
     		 undef,
     		 10,
     		 'true');
     
          	   print "<P><EM>Any parting comments?</EM><BR>";
          	   print $query->textarea('Comments',undef,10,50);
     
          	   print "<P>",$query->reset;
          	   print $query->submit('Action','Shout');
          	   print $query->submit('Action','Scream');
          	   print $query->endform;
          	   print "<HR>\n";
     }
     
     sub do_work {
          	   my($query) = @_;
          	   my(@values,$key);

     print "<H2>Here are the current settings in this form</H2>";

     foreach $key ($query->param) {
      	      print "<STRONG>$key</STRONG> -> ";
      	      @values = $query->param($key);
      	      print join(", ",@values),"<BR>\n";
               }
      	}
     
      	sub print_tail {
     print <<END;
      	<HR>
      	<ADDRESS>Lincoln D. Stein</ADDRESS><BR>
      	<A HREF="/">Home Page</A>
      	END
      	}

BUGS
====

   This module doesn't do as much as CGI.pm, and it takes longer to load.
Such is the price of flexibility.

SEE ALSO
========

   *Note URI/URL: URI/URL,, *Note CGI/Request: CGI/Request,, *Note
CGI/MiniSvr: CGI/MiniSvr,, *Note CGI/Base: CGI/Base,, *Note CGI: CGI,


