package TripodPage; ################# # TripodPage.pm # ############################################################################## # TripodPage is a module that makes it easier for you to generate dynamic # # pages from your scripts. TripodPage does two big things for you: # # # # 1. It generates an HTTP header for you, so you don't have to go to the # # trouble of outputting a 'Content-Type: text/html\n\n' or all that # # other stuff. This is especially helpful if, like a lot of people, # # you don't know what an HTTP header is supposed to look like! # # 2. It lets you take an HTML template and fill in certain values that you # # want to be dynamic. For example, if you wanted your script to output # # a page that always showed the current time, you could do that easily # # with TripodPage. # # # # The functions you care about are: # # # # * sendPage(); # # * sendNonCachedPage(); # # * printHeader(); # # # # sendPage() is the most important one. sendPage() takes an html file, # # in any variables that it contains, and spits the page out to the web # # server. It takes two arguments; the first is the location of the html # # file, and the second is a reference to a hash of variables. If you aren't # # familiar with hashes or with variables, just follow the example and you # # should do fine. Here's the example - this one's long, with a couple of # # parts to it: # # # # $page_location = 'example.html'; # # $variable_hash{timezone} = $ENV{TZ}; # # $variable_hash{ip_address} = $ENV{REMOTE_HOST}; # # $variable_hash{browser} = $ENV{HTTP_USER_AGENT}; # # $PAGE->sendPage($page_location, \%variable_hash); # # exit; # # # # The 'example.html' file referred to at the beginning might look something # # like this: # # # # # # Example Page # #
# #

Example Page

# # You are coming in from this timezone: $timezone
# # You are using the $browser browser. Your ip address is $ip_address. # # # # # # Together, this script and html file will output a page that shows the # # viewer's browser, ip address, and timezone. First, the script specifies # # the name of the html file that we will be using. Second, it creates a # # hash which contains all the variables contained within the page - in this # # case, 'timezone', 'ip_address', and 'browser' - and assigns values to each # # of them. Note that in this case it is getting the values out of a special # # hash called %ENV, which contains environment variables that all CGI # # scripts have access to, but you could have different variables that get # # their values from other places, like random numbers, the time or date, # # input from a form, etc. Finally, the script calls sendPage() to take the # # html file and fill in the variables with the contents of the hash. # # sendPage() looks at the html and searches for words preceded by dollar # # signs. In our example file, it finds $timezone, $browser, and # # $ip_address. Each of these then gets replaced by the values from the # # hash. So the output might look something like this: # # # # # # Example Page # # # #

Example Page

# # You are coming in from this timezone: US/Eastern
# # You are using the Mozilla/4.61 [en] (Win98; U) browser. Your ip address # # is 208.7.131.186. # # # # # # That's what you'd see if you were using my personal computer at Tripod - # # you'd see something quite different. This is what's cool about # # sendPage() - it lets you present different information in your page under # # different circumstances. # # # # We can go over the last two functions quickly. sendNonCachedPage() works # # just like sendPage(), except that it also tells the browser not to cache # # the page that is sent. This is a good idea if the information you are # # sending back changes from moment to moment, and you want to make sure that # # a visitor who reloads the page always gets the newest information. # # # # printHeader() just outputs the HTTP header that tells the browser you are # # outputting an HTML page from your script. If your script is outputting # # something besides HTML, you can also pass it the appropriate MIME-type for # # your output, and it will change the header accordingly. You can use it # # like this: # # # # $PAGE->printHeader(); # # print "A really simple page."; # # exit; # # # # That will output a page which says 'A really simple page.' and nothing # # else. You might want to use printHeader() instead of sendPage() if you # # are creating such a dynamic web page that you need write all the HTML from # # within your script, rather than using an HTML file as a template and # # filling in variables. ############################################################################## sub new { my $class = shift; my $self = {}; bless $self, $class; # Initialize variable where page content will be stored. $PAGE_CONTENT = ''; # Bool to keep track of whether the header has been sent. $HEADER_SENT = 0; # Bool to determine whether we display ad. $DISPLAY_AD = 1; return $self; } sub sendPage { my($self,$template_location_or_string_ref,$hash_ref) = @_; # Define this important string ref. my $page_content_ref = \$PAGE_CONTENT; # Branch depending on the type of argument passed. if (!ref($template_location_or_string_ref)) { # Not passed a ref (to SCALAR). Fill $page_content. $self->fillString($page_content_ref, $template_location_or_string_ref); # For dev: Tack on the location of the template in a comment for # reference. if ($ENV{'SERVER_NAME'} =~ /^\w+-dev\.tripod\.com/) { $$page_content_ref .= "\n\n"; } } else { $page_content_ref = $template_location_or_string_ref; } # Remove ads if necessary. if ($DISPLAY_AD != 1) { $$page_content_ref =~ s|[\s\S]*?||ig; } # Interpolate variables as needed. $self->varSubstitution($page_content_ref,$hash_ref); # Print the header if needed. $self->printHeader() if (!$HEADER_SENT); # Print the page content to STDOUT. print $$page_content_ref; # Record that the header has been sent. $HEADER_SENT = 1; } sub sendNonCachedPage { my $self = shift; # HTTP/1.0 caches should not store responses that have already expired print "Expires: Thu, 27 Feb 1997 21:42:25 GMT\n"; # HTTP/1.1 headers, in case caches recognize at least one of 'em print "Cache-control: no-cache\n"; print "Cache-control: no-store\n"; print "Cache-control: private\n"; $self->sendPage(@_); } sub printHeader { my($self,$mime_type) = @_; if (!defined($mime_type) || $mime_type eq '') { print "Content-type: text/html\n\n"; } else { print $mime_type, "\n\n"; } $HEADER_SENT = 1; } # Set $$content_ref to the content of the template file passed. sub fillString { my($self,$content_ref,$template_location) = @_; my($old_newline); $old_newline = $/; undef $/; open(PAGE,"< $template_location"); $$content_ref = || "Couldn't open $template_location"; close(PAGE); $/ = $old_newline; } # Interpolate variables into string, but only if values are defined. sub varSubstitution { my($self,$string_ref,$hash_ref) = @_; $$string_ref =~ s|\$(\w+)|returnValueOrKey($1,$hash_ref)|eg; } sub returnValueOrKey { ($key,$hash_ref) = @_; if (defined($$hash_ref{$key})) { return $$hash_ref{$key}; } else { return '$' . $key; } } 1;