8.3.8 More on The CGI.pm Module
8.3.8 More on The CGI.pm Module
We have seen the use of the CGI.pm module in programs discussed earlier. However, our use has been very minimal; we have used it only for capturing parameters coming to a Web server from a CGI program, for limiting the size of CGI data sent by a form, and for disabling file uploads. The CGI.pm module is quite a bit more powerful than what we have seen. The CGI.pm module is large and has a very large number of functions that help construction of dynamic Web pages. For example, it provides us with functions for the following:
• Creating HTML tags of all kinds. For example, the function h1 produces the first-level HTML header <H1>. The module provides boilerplate HTML that may reduce typing and coding, and consequently, errors associated with typing and coding. The module also has a function called table that can be used to produce HTML tables. In fact, the module claims to have a function corresponding to every HTML tag. The name of a function or method is the same as the name of the corresponding HTML tag. Case does not
matter for names of CGI.pm functions, methods and other symbols the module exports.
• Not only can the CGI.pm module capture what has been sent by a server, it can manipulate them in various ways. For example, it can delete one or more parameters and make them unavailable. It can read the parameters into a hash instead of into an array.
• It is especially useful in writing CGI programs that send out HTML forms in response. These forms can contain information sent out by the original CGI program. This allows session continuity from form to form when several forms are used in sequence.
• The CGI.pm module also provides ability to deal with file uploads in HTML forms.
• The CGI.pm module allows the creation of cookies that can be sent back to the browser from which the CGI program was originally invoked.
• The CGI.pm module also provides facilities to deal with cascading style sheets, and frames among other things.
• In addition, there is a large number of modules which are subclasses of the CGI class of modules. These modules perform a wide variety of tasks such as caching of the results of time-intensive CGI scripts, for debugging CGI programs, for using encryption to send form data, for dealing with XML forms, for dealing with cookies, for buffering output when building output, for dealing with the Apache Web server sessions, for validating credit card information sent through a form, for dealing with HTML image maps, for handling database access, etc.
We do not have room in this book to discuss everything that the CGI.pm module and other CGI:: modules can do. We discuss just a small fraction of the possibilities in this Chapter. Those who are interested in finding more about the modules should go to the Comprehensive Perl Archive Network (www.cpan.org) and use one of the search engines to find the relevant modules, read the documentation, download and install and run some simple programs to determine if the module is suitable for the purpose at hand.
The following program is a rewrite of of the program that echoes values of CGI parameters that is discussed in Section 8.3.7. The program uses the functional interface to construct the HTML code that is returned by the the the the CGI program.
Program 8.8
#!/usr/bin/perl -Tw
#assamListFormEcho2.pl
use CGI qw(:standard -nodebug);
use CGI::Carp qw(fatalsToBrowser);
use Untaint;
use strict;
#######Set CGI size limit; disable file upload
$CGI::POST_MAX = 1024; #max 1024 bytes posts
$CGI::DISABLE_UPLOADS = 1;
##########################
my $email = param ("email");
$email = untaint (qr/^\w+@\w+$/, $email);
my $firstName = param ("firstName");
$firstName = untaint (qr/^[a-z]+$/i, $firstName);
my $lastName = param ("lastName");
$lastName = untaint (qr/^[a-zA-Z]+$/, $lastName);
my $address = param ("surfaceAddress");
$address = untaint (qr/^[\d\w\s]+$/, $address);
my $telephone = param ("telephoneNumber");
$telephone = untaint (qr/^\d+$/, $telephone);
my $motherName = param ("motherMaidenName");
$motherName = untaint (qr/^[a-zA-Z]+$/, $motherName);
my $homeTown = param ("homeTown");
$homeTown = untaint (qr/^[a-zA-Z]+$/, $homeTown);
#######Write to browser
print header ("text/html");
print start_html (-title => "Subscribe to Assam List",
-BGCOLOR => "BISQUE");
print qq{}, h1 ("Subscribing to Assam List"),
qq{};
print table ({-border => 0},
caption ("Details You Supplied"),
Tr( th({-align => "LEFT"}, ["Email:"]), td ($email)),
Tr( th({-align => "LEFT"}, "First Name:"), td ($firstName)),
Tr( th({-align => "LEFT"}, "Last Name:"), td ($lastName)),
Tr( th({-align => "LEFT"}, "Address:"), td ($address)),
Tr( th({-align => "LEFT"}, "Telephone Number:"), td ($telephone)),
Tr( th({-align => "LEFT"},
font({-color => "red"}), "Mother's Maiden Name:"),
td ($motherName)),
Tr( th({-align => "LEFT"},
font({-color => "red"}), "Home Village/Town/City:"),
td($homeTown))
);
print qq{
This is just a test form handling program that echoes what you entered
and does nothing else},
p,
qq{Thank you!},
p,
qq{Assam List Administrators},
p;
print end_html;
The initial part of the program is exactly the same as the program in Section 8.3.7. It uses the CGI.pm module’s functional interface, and the CGI::Carp.pm module to send details of fatal error to the browser. It also sets the maximum length of data entered to be 1024 bytes. It explicitly disallows file uploads.
The program reads the values of the CGI parameters and launders them using the untaint method of the Untaint.pm module. Once the parameter values have been untainted, it creates the HTML page to be returned to the browser. It, more or less exclusively, uses HTML creating functions provided by the CGI.pm module to do so.
The first thing a CGI program needs to do is create one or more valid HTTP headers.
print header ("text/html");
At a minimum, it needs to tell the browser the type of content that it is sending. This is done by sending the content-type HTTP header. There can be other HTTP headers as well. The last HTTP header line must be followed by a blank line. The header function provided by the CGI.pm module produces one or more HTTP header lines. Only one call must be made to header even if several HTTP headers are produced. The header
function can be called with one argument, the MIME type of the information returned by the CGI program. If it is called with no arguments, text/html is assumed to be the default content type. The header function can set values of other HTTP headers such as content-length, cookies, and status, etc. In such a case, the arguments should be provided in name-value pairs. How name-value pairs can be specified in a function call is discussed later.
Next, the program generates <HTML> and <BODY> HTML tags. These tags are produced by the start_html CGI.pm function. All parameters to the start_html function are optional. Thus, one can make the call
print start_html ();
to produce just the <HTML> and <BODY> tags in sequence, and nothing else. Just like most other CGI.pm functions, arguments can be given to the start_html function as name-value pairs.
print start_html (-title => "Subscribe to Assam List",
-BGCOLOR => "BISQUE");
If name-value pairs are provided to a CGI.pm function, the name and the value of a pair are separated by =>. Various pairs are separated by the comma. The name of a parameter is the name of the corresponding HTML tag to be produced, preceded by the dash. The start_html function understands -title, -author, -base, and a few other parameters. These produce corresponding HTML tags within the HTML head, i.e., within <HEAD> and </HEAD>. Any “unrecognized" parameters can be provided to the start_html function as well. For example, the -BGCOLOR parameter is such a parameter. Unrecognized parameters are added as attributes to the <BODY> HTML tag. The call to start_html given above produces the
following HTML code.
<head><title>Subscribe to Assam List</title></head><body bgcolor="BISQUE">
Note that the HTML tags and attributes produced by the CGI.pm module are in lower-case although they are case-insensitive. Next, the program produces a first-level header in blue color.
print qq{<FONT COLOR="BLUE">}, h1 ("Subscribing to Assam List"),
qq{</FONT>};
h1 is the function that produces the <H1> and </H1> tags with the actual text of the header included in between. This line shows that printing of strings and calls to CGI.pm functions can be mixed. qq is the quoting function that allows variable interpolation. Using qq is the same as including the string within double quotes.
Next, the program produces an HTML table, and then prints some strings interspersed with the printing of some <P> tags. The CGI.pm function p () produces a <P> tag. As noted earlier, the name of a CGI.pm function is usually the same as the name of the corresponding HTML tag. Also, the case used in calling a CGI.pm function does not matter. Finally, the
program makes a call to end_html.
print end_html;
This produces
</body></html>
in HTML.
Let us now look back at the creation of the HTML table.
print table ({-border => 0},
caption ("Details You Supplied"),
Tr( th({-align => "LEFT"}, ["Email:"]), td ($email)),
Tr( th({-align => "LEFT"}, "First Name:"), td ($firstName)),
Tr( th({-align => "LEFT"}, "Last Name:"), td ($lastName)),
Tr( th({-align => "LEFT"}, "Address:"), td ($address)),
Tr( th({-align => "LEFT"}, "Telephone Number:"), td ($telephone)),
Tr( th({-align => "LEFT"},
font({-color => "red"}), "Mother's Maiden Name:"),
td ($motherName)),
Tr( th({-align => "LEFT"},
font({-color => "red"}), "Home Village/Town/City:"),
td($homeTown))
);
The table function produces the HTML table. We know that an HTML tag such as <TABLE> can take one or more attributes with corresponding values. For example, an attribute that the <TABLE> tag can take is BORDER. If attribute-value pairs are provided to a CGI.pm HTML-producing function, the pairs are included inside curly braces. For example, the code given above produces
<table border="0">
on top of the HTML table. TABLE is the HTML tag, and BORDER is the attribute with a value of 0. If several attributes are provided, they are all included inside curly braces. The pairs are separated from one another using the comma. An HTML tag such as TABLE takes attributes that are placed inside the <TABLE> tag. A table also has content that is included inside the <TABLE> and
</TABLE> tags. The content is provided to the table CGI.pm function as arguments that are separated from each other using the comma. The first content argument provided to the table function is caption that takes a string giving the value of the caption. A table has rows and a row has one or more elements or cells in it. In HTML, the contents of a row are included inside <TR> and
</TR> tags. A cell can be of two types: a table head element included inside <TH> and </TH>, and a table data element included inside <TD> and </TD> tags. In CGI.pm, a table row is specified using the tr function, and a table head element by using the th function, and a table data element using the
td function. Calls to tr are included as arguments to the table function; calls to th and td are included as arguments to the tr function. As mentioned earlier, the names of CGI.pm functions are case-insensitive, although Perl, in general, is case-sensitive. There is a function in Perl called tr that performs
text stubstitution or text transliteration. The CGI.pm function tr clashes with the text transilteration function tr. Therefore, the CGI.pm documentation advises using Tr, with T in upper case, for the function that creates a table row. The Tr, td, th and many other functions take arguments that correspond to HTML tag attributes. In the program given above, each call to th takes two arguments. The first argument to th is included inside curly braces indicating it corresponds to an attribute for the tag <TH>. There can be several attribute name-value pairs although we have only one pair in each call to th in the program. The name of the attribute is the same as the name of the HTML attribute, but it is preceded by a dash. For example,
th({-align => "LEFT"}, ["Email:"])
translates to
<th align="LEFT">Email:</th>
It is instructive to compare the Perl code and the corresponding HTML to figure out clearly how the CGI.pm functions work. The complete HTML table produced is quite similar to the table seen in Section 8.3.7.
In general, CGI.pm is a module with a large number of functions, a substantial subset of which is used for producing HTML fragments. Some of the functions are quite versatile taking unnamed or named arguments. The functions can also take attribute arguments. The names of attributes are the same as the names of corresponding HTML tag attributes, but are preceded by a dash. Attribute arguments are included inside curly braces. If a list is given as an argument, it is usually included in square brackets to create an anonymous array. There are several other details that one needs to know to be able to program well using the
CGI.pm module. Sometimes, the syntax of CGI.pm function calls can become quite confusing with all the variations that are allowed. Also, it seems to the author that it may sometimes be more straightforward to produce the HTML code directly rather than using CGI.pm functions as intermediary in the process. In addition, it is possible to use a module such as HTML::Template to use an HTML template, stored in a file, with variable interpolation. However, whether one produces HTML directly, or uses
CGI.pm functions, depends on an individual’s choice. The author uses the HTML producing functions of the CGI.pm module sparingly. That is why, in the programs that follow there are not many CGI.pm function calls.
