Online Learning Applications for Technical English


Home
Syllabus
Assignments

Instructor



Producing Homepages

Example 3: Write a Perl CGI program to display all or part of a data file depending on the request by a user.

Imagine that we have the following data file:

Filename: books.dat
Randal L. Schwartz and Tom Phoenix, "Learning Perl"
Larry Wall, Tom Christiansen, and Jon Orwant, "Programming Perl"
Craig Patchett and Matthew Wright, "The CGI/Perl Cookbook"
John R. Hubbard, "Programming With Java"
‘ˆδr”V, "Perl‘–@"
Daniel J. Berlin, et al, "CGI Programming"

Let us write a program which will: 1) print all contents of this file OR 2) print only the lines containing some keyword specified by the user. To get this information from the user, let us create an HTML form. The CGI program should do the following:

  Step 1   Read user input from the form.

Step 2
Open the data file and read the contents into an array.

Step 3
Print contents in a homepage table according to the user input.

Prepare a file as follows:

Filename: disp_books.cgi
#!/usr/bin/perl

#------------------------------
# [11/6/2002] - File created.
#------------------------------

#-----------
# Variables
#-----------
$DATA_FILENAME = 'books.dat';

$TRUE = 1;
$FALSE = 0;

$CGI_NAME = 'disp_books.cgi';

#-----------------------------------------------
# Step 1:  Read user input.
#-----------------------------------------------
  if( $ENV{REQUEST_METHOD} eq 'POST' )
  {
    read(STDIN,$input,$ENV{'CONTENT_LENGTH'});
  }
  elsif( $ENV{REQUEST_METHOD} eq 'GET' )
  {
    $input = $ENV{QUERY_STRING};
  }
  else 
  {
    print "Content-type:  text/html\n\n";
    print "This program does not support the ";
    print "<B>$ENV{REQUEST_METHOD}</B> ";
    print "httpd request method.\n";
    exit 1;
  }

# Format input fields (replace '+' with spaces,
# split pairs at '&', split each pair at '=').
  $input =~ tr/+/ /;
  @fields = split(/\&/,$input);
  $input = '';

  foreach $field_pair (@fields)
  {
    ($field, $data) = split(/=/,$field_pair);
    $field =~ s/%(..)/pack("c",hex($1))/ge;
    $data =~ s/%(..)/pack("c", hex($1))/ge;
    $tokens{$field} = $data;
  }

  @fields = ();

#-----
# Step 1-1: Check for input errors.
#-----
  if( ($tokens{'PRINTING_RANGE'} 
    eq 'KEYWORD_LINES_ONLY')
      && ($tokens{'KEYWORD'} eq '') )
  {
    &invalid_keyword_error;
  }
#-----------------------------------------------
# Step 2: Open data file and read contents into 
#  a "lines" array.
#-----------------------------------------------
  open( DATA_FILE, "< $DATA_FILENAME" )
    or die "Cannot open data file $DATA_FILENAME: $!";
  chomp( @lines = <DATA_FILE> );
  close( DATA_FILE );
#-----------------------------------------------
# Step 3:  Print HTML contents according to
#  user's requests.
#-----------------------------------------------
# Print header.
  print "Content-type:  text/html\n\n";

# Print HTML.
  print <<END;
<HTML>
<HEAD>
</HEAD>
<BODY>
END

#---------------------------------
# Step 3-1: Check printing range.
#---------------------------------
  if( $tokens{'PRINTING_RANGE'} eq 'ALL' )
  {
    foreach $line (@lines)
    {
      print "$line<BR>\n";
    }
  }
  else
  {
    $found_match = $FALSE;

# Print lines containing the keyword.
    foreach $line (@lines)
    {
      if( $line =~ $tokens{'KEYWORD'} )
      {
        print "$line<BR>\n";
        $found_match = $TRUE;
      }
    }

    if( $found_match eq $FALSE )
    {
      print "(no lines matched the search ";
      print "for: $tokens{'KEYWORD'})<BR>\n";
    }
  }

# End the homepage.
  print <<END;
</BODY>
</HTML>
END

  exit;

# Done.
#-------------
# Subroutines
#-------------
sub invalid_keyword_error
{
  print "Content-type:  text/html\n\n";
  print "Please enter a keyword to search.  ";
  print "($CGI_NAME)<BR>\n";
  print "Use the [BACK] button on your browser ";
  print "to return.\n";
  exit 1;
}
[ Test form ]

[ Back ]