Creating Bulletin Boards
Creating a simple CGI message board
The HTML Templates
The Bulletin Board Script
Displaying the Message List
Displaying Messages
Adding New Messages
Adding Replies
Expiring Messages
The Complete Bulletin Board Script


[Previous] [Next]


Displaying Messages


Recall from the code in the previous section that the message subject for each header is a link to the message file. The actual HTML looks like this:
 <A HREF="/cgi-bin/board.pl?message=$message_file&list=$i"><B>$subject</B></A>


where $message_file is the file containing the entire message, $i is the list file, and $subject is the message's subject. Notice how the link calls the CGI script board.pl. This is the name of your bulletin board script file. So, each link calls the bulletin board script again and passes two parameters, the message file name and the list file name. In this section, you develop the Display_Message subroutine, which takes these two parameters and displays the corresponding message file.

Your Display_Message subroutine first needs to open the message file, the message's list file, and the message template file. Once these files are opened, their contents is read into three arrays: @message, @list, and @template. This is done with the following lines of Perl code, which are similar to open statements used in the previous section:

 open(TEMPLATE,"$message_template") || die "Content-type: text/html\n\nCannot open
 template!";
 @template = <TEMPLATE>;
 close(TEMPLATE);

 open(MESSAGE,"$message_dir/$data{\"message\"}") || die "Content-type:
 text/html\n\nCannot open message!";
 @message = <MESSAGE>;
 close(MESSAGE);

 open(LIST,"$list_dir/$data{\"list\"}") || die "Content-type: text/html\n\nCannot
 open message!";
 @list = <LIST>;
 close(LIST);


The message's list file is opened so that the message's subject can be obtained easily. Recall from the section "The HTML Templates" that the message's subject is placed in the title of the Web page and as the default text in the subject field of the Reply form at the bottom of the Page (as shown earlier in Figure 4). To get the header information of the current message, you need to loop over all the contents of the list file until you find the line containing the correct header. Because the @list array contains the contents of the list file, you can just loop over the array until you find the correct element. To accomplish this, you use Perl's foreach statement, which loops over each element of the array. Here is the entire foreach statement and body:
 foreach (@list) {
   # Split each message header from the message list file.
   (undef, $subject, undef, $message_file) =
            split(/::/);
   chop $message_file;

   # Exit the loop when the message has been found.
   last if $message_file == $data{'message'};
 }


The first lines in the body of the foreach loop split the header information, as you did in the Display_Message_Lists subroutine. But here the split statement does not specify an argument to split. In Perl, when there is no argument for the split statement, the contents of the $_ variable are split. This is a special variable that, in the context of the preceding foreach loop, is set to the current element in the @list array for each iteration of the loop. Finally, the last statement in the body of the foreach loop compares the value of the $message_file variable, which was just obtained from the header information in the @list array, with the value of the message file that was passed to the script as an argument. The data passed to your bulletin board script is URL decoded and placed into the %data associative array with the User_Data subroutine you have used throughout this book. If the values of these two variables match, the current element of the @list array is the correct header line for the message the user selected for display. So, the last statement at the beginning of the line causes the loop to exit when the conditional is true.

Now that you have obtained the subject from the list file's header information and have read in the entire message from the message file, you can insert the information into the HTML template file and send the modified template back to the user's Web browser. You do this with the following lines of Perl:

 $template[2] =~ s/XXXX/$subject/ge;

 unless ($subject =~ /^re:/i) {
   substr($subject, Ø, Ø) = "Re: ";
 }

 $template[2Ø] =~ s/YYYY/$subject/ge;
 $template[26] =~ s/ZZZZ/$data{'list'}/ge;

 splice(@template, 4, Ø, @message);

 print "Content-type: text/html\n\n";
 print @template;


The first line places the message's subject in the HTML line that contains the <TITLE> tags. Recall from Listing 2 that this is the third line of the file, which when read into the @template array corresponds to index 2. The unless conditional checks whether the subject already begins with the letters re:, ignoring case. The check is performed by using the regular expression /^re:/i, which is true if the first three characters of the $subject variable are re:, Re:, rE:, or RE:. If they are not, the string Re: is placed at the beginning of the contents of the $subject variable. Then the modified subject is substituted for the YYYY placeholder. Remember that this placeholder was for the default value of the subject field in the Reply form at the bottom of the Web page the user will see. Next, the list file name is placed into the hidden field of the Reply form, replacing the ZZZZ placeholder. The splice statement, which you used in the Display_Message_List subroutine, inserts the contents of the message into the beginning of the HTML template. Finally, the modified version of the template is sent to the user's Web browser along with the required parsed header.

You can now create the Display_Message subroutine by placing all the code you have developed so far within a subroutine body. You also need to add the declarations of the local variable. Listing 4 contains the complete code for the Display_Message subroutine.

Listing 4: The Display_Message Subroutine
sub Display_Message {
   local (%data) = @_;
   local (@template, @list, @message, $subject, $message_file);

   # Open and read in the template
   open(TEMPLATE,"$message_template") || die "Content-type:
 text/html\n\nCannot open template!";
   @template = <TEMPLATE>;
   close(TEMPLATE);

   # Open and read in the message file
   # Windows users need to change the string
 "$message_dir/$data{\"message\"}"
   # to "$message_dir\\$data{\"message\"}"
   open(MESSAGE,"$message_dir/$data{\"message\"}") || die "Content-
 type: text/html\n\nCannot open message!";
   @message = <MESSAGE>;
   close(MESSAGE);

   # Open and read in the list file
   # Windows users need to change the string
 "$list_dir/$data{\"list\"}" to
   # "$list_dir\\$data{\"list\"}"
   open(LIST,"$list_dir/$data{\"list\"}") || die "Content-type:
 text/html\n\nCannot open message!";
   @list = <LIST>;
   close(LIST);

   # Find the subject for the message to be displayed.
   foreach (@list) {
     # Split each message header from the message list file.
     (undef, $subject, undef, $message_file) =
              split(/::/);
     chop $message_file;

     # Exit the loop when the message has been found.
     last if $message_file == $data{'message'};
   }

   # Put the subject in the <TITLE> line of the template.
   $template[2] =~ s/XXXX/$subject/ge;

   # Format the subject line for the Reply form at the end of the page.
   unless ($subject =~ /^re:/i) {
     substr($subject, Ø, Ø) = "Re: ";
   }

   # Insert the subject and list into the template.
   $template[2Ø] =~ s/YYYY/$subject/ge;
   $template[26] =~ s/ZZZZ/$data{'list'}/ge;

   # Insert the message into the template and send it to the user's Web
 browser.
   splice(@template, 4, Ø, @message);

   print "Content-type: text/html\n\n";
   print @template;

 }






[Previous] [Next]