CGI and Perl

Displaying Appointments on a Specific Day: disp_day.cgi

Each day in the calendar is a link to disp_day.cgi, along with the date URI encoded. For example, a link to June 25, 1997, looks like this:

http://myserver.com/hypercal/disp_day.cgi?6&25&1997

The disp_day.cgi script, shown in Listing 11.3, simply reads the day from the URI, reads the datebook database, looks up the Julian date to reference the database entry, and formats an HTML page based on the contents of the database (if any) on that day.

Listing 11.3. disp_day.cgi.

#!/usr/bin/perl
 #  Display Day.  Reads in database and prints appointments for the
 #  selected day.  Allows option of adding new appointment.
 #
 require `variables';
 require `httools.pl';
 &header;
 #  Determine if this is a personal calendar;
 ($sub=$ENV{`PATH_INFO'})=~s#^/##;
 if ($sub=~/personal/){require $personal};
 #   Read date from QUERY_STRING
 $info=$ENV{`QUERY_STRING'};
 ($month,$day,$year)=split(/&/,$info);
 #  Print titles to html page
 &month_txt("$month");
 &title("Appointments for $month_txt $day, $year.");
 print "<h2>Appointments for $month_txt $day, $year.</h2><hr>";
 #  Read in database.
 $any="no";     #  Flag which determines if appts were found.
 open (DATES, "$datebook");
 @dates=<DATES>;
 close DATES;
 &julean($month,$day,$year);   #    Julean date of day in question.
 #  Checks database for listings of that day.
 print "<table border width=100%>";
 print "<tr><th> Time <th> Event <th> Name <br>";
 for $date (@dates)    {
 ($julean,$time,$endtime,$desc,$name,$id)=split(/~~~/,$date);
 if ($julean==$jule) {
 print "<tr><td>";
 if ($time eq "00:00" && $endtime eq "00:00")  { print "(All day) ";}
 else {
 #  am/pm the time
 ($hr,$min)=split(/:/,$time);
 if ($hr==24) {$hr="12";
         $ampm="am"}
 else {
 if ($hr<12) {$ampm="am"}
 else {$hr-=12;
     if ($hr==0){$hr=12};
     $ampm="pm"};
 }    # end else
 $time=$hr.":".$min." ".$ampm;
 print "$time";}
 if ($endtime eq "00:00") {}
 else {
 #  am/pm the time
 ($hr,$min)=split(/:/,$endtime);
 if ($hr<=12) {$ampm="am"}
 else {$hr-=12; $ampm="pm"};
 if ($hr==0){$hr="12"};
 $endtime=$hr.":".$min." ".$ampm;
 print " - $endtime ";}
 print "<td> $desc <td> $name <br>";
             $any="yes";}
             }
 if ($any eq "no") {print "<tr><td colspan=3><center>
                           <b>** No appointments **</b></center><br>";}
 print "</table>";
 print "<hr>";
 print "<a href=$base_url$add_date?$month&$day&$year>Add an appointment</a><br>";
 print "<a href=$base_url$del_date?$month&$day&$year>
        Delete an appointment</a><br>" unless ($any eq "no");
 print "<a href=$base_url$hypercal?$month&$year>Back</a> to the calendar.";
 &footer;

Let's take a look at how disp_day.cgi works. The database file is opened as a file handle (DATES) and read line by line into an array (@dates). Once read into the array, the file handle is closed.

 open (DATES, "$datebook");
 @dates=<DATES>;
 close DATES;

Since entries are indexed in the database by their Julian date, referred to in the code as "julean" date, the Julian date is constructed from the $month, $day, and $year submitted in the URI:

&julean($month,$day,$year);   #    Julean date of day in question.

Now that we've read in the database and know what Julian day we're looking for, the real work can be done. The code that follows sets up a HTML table, then steps through the @dates array until the specified date is reached:

#  Checks database for listings of that day.
 print "<table border width=100%>";
 print "<tr><th> Time <th> Event <th> Name <br>";
 for $date (@dates)    {

When a line in the database is found that matches the specified date, it is broken down using the split operator into six variables: $julean, $time, $endtime, $desc, $name, and $id.

($julean,$time,$endtime,$desc,$name,$id)=split(/~~~/,$date);

From these elements, an HTML table of events for that day is generated. The variables are embedded into HTML tables. Notice that the <table> tag is set up before any looping begins. To properly create tables with loop structures in your code, define the table before the loop. Each loop should begin with <TR><TD> tags and end with </TD></TR>. The </table> tag should be placed after the loop. This is obvious once you think about it and look at the HTML generated by an improperly written program.