home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


CGI Programming on the World Wide Web

Previous Chapter 6 Next
 

6. Hypermedia Documents

When you're looking around on the Web, going from site to site, you may have seen virtual documents that greet you, pages with graphics that are created "on the fly," or sizzling animations. These are all examples of graphic creation and manipulation using CGI. There are numerous tools and utilities that allow you to create documents such as these very quickly and easily.

6.1 Creating Dynamic Home Pages

What is a dynamic (or virtual) home page? It's a document that looks different when viewed at different times or by different people. For example, you may want to display a random fortune cookie when someone visits your home page. If you conduct business on the Web, you might want to use a dynamic document to advertise different products when someone accesses the document.

In order to set up a virtual home page, you have to modify certain configuration settings to ask the server to execute a CGI program instead of displaying a static HTML file. Normally, the NCSA server looks for the file index.html in the document root directory and displays it.

The following line when added to the server resource configuration file (srm.conf) forces the server to execute the CGI program index.html (a Perl program doesn't have to end with a .pl extension):

AddType application/x-httpd-cgi index.html

The AddType server directive was originally introduced in Chapter 1, The Common Gateway Interface. It allows you to execute CGI programs located outside the cgi-bin directory.

Under the CERN server, you can do something similar by adding the following line to httpd.conf:

Exec /index.html /usr/local/etc/httpd/cgi-bin/index.pl

Now, let's create a simple virtual home page that displays a greeting, based on the time of the access, and a message indicating whether the webmaster is currently logged in. Of course, this is a very simple example that illustrates the creation of a home page with dynamic information. You can also create a virtual home page using Server Side Includes, as shown in Chapter 5, Server Side Includes.

#!/usr/local/bin/perl
print "Content-type: text/html", "\n\n";
$webmaster = "shishir";
($seconds, $minutes, $hour) = localtime (time);

The localtime function takes the current time (in seconds since 1970) and returns a nine-element array consisting of the date and time for the current time zone. We will be using only the first three elements of the array, which contain the seconds, minutes, and hour values (in the military 24-hour format).

If your system's time zone is not configured properly, you will get the date and time for the Greenwich time zone (GMT). In such a case, you will need to use the TZ environment variable to set the proper time zone before you call the localtime function:

$ENV{'TZ'} = 'EST';

This sets your time zone to Eastern Standard Time (EST). You can see some of the other time zones by looking at the following document: http://wwwcrasys.anu.edu.au/reference/world.timezones.html

To return to the program:

if ( ($hour >= 23) || ($hour <= 6) ) {
        $greeting = "Wow, you are up late";
} elsif ( ($hour > 6) && ($hour < 12) ) {
        $greeting = "Good Morning";
} elsif ( ($hour >= 12) && ($hour <= 18) ) {
        $greeting = "Good Afternoon";
} else {
        $greeting = "Good Evening";
}

Since the localtime function returns the hour in a 24-hour format, we can use this to our advantage. It is much easier to select a greeting based on this format because the time scale is continuous from 0-23, and we don't have to worry about determining whether an hour value of "12" indicates 12:00 A.M. or 12:00 P.M.

if ($hour > 12) {
        $hour -= 12;
} elsif ($hour == 0) {
        hour = 12;
}
$time = sprintf ("%02d:%02d:%02d", $hour, $minutes, $seconds);

For display purposes, however, the hour is converted into the regular 12-hour format. The sprintf function formats a string according to the field specifiers. In this case, we want the hours, minutes, and seconds to be two digits in length, so a minute value of "9" will be displayed as "09". The formatted string is stored in the $time variable.

open(CHECK, "/usr/bin/w -h -s $webmaster |");
if (<CHECK> =~ /$webmaster/) {
        $in_out = "I am currently logged in.";
} else {
        $in_out = "I just stepped out.";
}

This open command might look strange to you if you're new to Perl. Instead of opening a file, it opens a pipe for input. In other words, Perl executes the UNIX program /usr/bin/w and redirects its output to the file handle CHECK. As you'll see throughout the book, this technique allows us to communicate with other utilities and programs by sending and receiving data through a pipe.

We pass the value stored in $webmaster as the argument to /usr/bin/w, which returns all of the system processes "owned" by $webmaster. We don't really need to know much about the processes. The only thing we're concerned about is whether any processes for $webmaster exist, indicating that he/she is logged in. Depending on this, the $in_out variable is set to a specific message.

  close (CHECK);

Once we're done, we close the file handle. It's a good practice to clean up all resources when you're done with them. Now, we're ready to output the information that we've gathered so far.

Instead of using a print statement to send each line to standard output, we'll use a "here" document. What is that, you may ask? See for yourself:

print <<End_of_Homepage;

This statement outputs everything below it to standard output until it reaches the string "End_of_Homepage." This saves us from typing print before each line that we want to output.

Since we output a MIME content type of text/html, we need to output some HTML information:

<HTML>
<HEAD><TITLE>Welcome to my home page</TITLE></HEAD>
<BODY>
$greeting! It is $time. Here are some of my favorite links:
.
. (some information)
.
<ADDRESS>
Shishir Gundavaram ($in_out)
</ADDRESS>
</BODY></HTML>
End_of_Homepage
exit(0);

The whole point of this exercise is that you can "embed" another language (like HTML) into a CGI script. But the variables from the enclosing script can be used within the HTML--Perl substitutes the right value for each variable. That's what makes this page dynamic rather than static. An important thing to note about "here" documents is that they follow the same conventions as the regular print statement, in that Perl will evaluate only variables, and not function calls and other expressions.

In this program, we output a MIME content type of text/html and followed that with the HTML code. But we're not limited to just creating dynamic HTML documents; we can create dynamic graphics as well, as we'll see next.


Previous Home Next
Common Errors Book Index CGI Examples with PostScript

HTML: The Definitive Guide CGI Programming JavaScript: The Definitive Guide Programming Perl WebMaster in a Nutshell