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;