Using the Docbase Form Generator

The form generator, formgen.pl, runs as a CGI script. It requires at least one argument, which tells the generator which instance of Docbase to use. For example, the CGI call:

/cgi-bin/Docbase/formgen.pl?app=ProductAnalysis

produces the form shown in Figure 6.1.

Default ProductAnalysis input form

Figure 6-1. Default ProductAnalysis input form

The assignment date, overridden by the |assigndate| marker, appears as static text. All other fields are open for input. However, this CGI call:

/cgi-bin/Docbase/formgen.pl?app=ProductAnalysis&duedate=1999-05-01&
  analyst=Jon%20Udell&company=Netscape&product=Collabra%20Server%204.0

produces the form shown in Figure 6.2.

Customized ProductAnalysis input form

Figure 6-2. Customized ProductAnalysis input form

Here, the generator, using the services of the Docbase::Input module, has overridden every replaceable marker with a computed or preassigned value. The analyst who completes this form needs to fill in only four of the fields: Title, Summary, Full Report, and Contact Info.

The form generator, formgen.pl, appears in Example 6.2. It’s brief, because most of the work is done by two modules: TinyCGI and Docbase::Input.

Example 6-2. The Docbase Form Generator

#!/usr/bin/perl -w

use strict;

use TinyCGI;                 # load basic CGI services
my $tc = TinyCGI->new();
print $tc->printHeader();
my $vars = $tc->readParse(); # get form variables into hashref

use Docbase::Input;         
my $di =                     # set up for this docbase
  Docbase::Input->new($vars->{app});  

$di->formGen($vars);         # pass form-variable hashref to form generator

TinyCGI, which I’ll use often, is a minimalistic CGI library. In it I’ve collected the four simple routines that are at the heart of all CGI programming—printHeader( ) to emit the all-important Content-type: header, readParse( ) to gather variables from GET and POST transactions and put them into a Perl hashtable, escape( ) to encode data for HTTP transmission, and unescape( ) to reverse the effects of escape( ). There’s nothing new here; TinyCGI simply repackages, for efficiency and convenience, the 1 percent of Perl’s standard CGI module that I use 99 percent of the time.

Generating an Input Form

As we’ve seen, the generated form varies according to arguments passed to formgen.pl. Docbase::Input accomplishes that by matching markers in the form template with arguments passed to it from formgen.pl. The formGen( ) method of Docbase::Input, shown in Example 6.3, is a typical example of a Perl-based template processor.

Example 6-3. The formGen Method

sub formGen                       # merge form template with form variables
  {
  my ($self,$vars) = @_;
  my $app = $self->{app};
  my $form =                      # create the template's name
    "$cgi_absolute/$app/form-template.htm"; 

  open(F,$form) or print "cannot open form template $form"; 

  while (<F>)                     # for each line of form template
    {
    if ( m/(!ACTION!)/ )          # rewrite form action
      {
      s#$1#$cgi_relative/$app/submit.pl#;
      }
    if ( m#</form># )             # tack on $app for next script's use
      {
      print "<input type="hidden" name="app" value="$app">
";
      }
    if ( m/|(w+)|/ )           # perform builtin function
      {
      my $fn = $1;                # grab function's name
      s/|$1|/&{$builtins{$fn}}/e;  # call function, replace marker with value
      }
    if ( m/~(w+)~/ )             # handle form variables that can be overridden
      {
      my $var = $1;               # grab variable's name
      my $val = $vars->{$var};    # access corresponding hashtable slot
      if (defined $val)           # if slot nonempty, print value on form
        {                         # and pass along in hidden variable
        s/~$var~/$val <input type="hidden" name="$var" value="$val">/;
        }
      else                        # turn other form variables into input boxes
        {
        s/~$var~/<input name=$var size=40>/;
        }
      }
    print $_;                     # emit the line
    }
  }

The drill is simple: read a line at a time, look for matches, do substitutions. In this example the $vars hashtable, which contains CGI name/value pairs received from TinyCGI, affords a concise way to map between those pairs and corresponding names that may or may not appear in the form. Perl’s s///e idiom likewise affords a concise way to convert a name that appears in the form into the result of a Perl function mapped to that name.

It’s trivial to build templates and Perl-based template processors, but the technique is very powerful. That’s why we’ll use it often.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset