CGI Scripting
Perl CGI Index
Basic CGI Scripting
Simple CGI Demo
Styling CGI Output
Sharing Perl Code
CGI Code Suite
CGI Environment
Next section...
Web Applications
Demo Source Code
Example #1 source
Example #2 source
Example #3 source
dwd.pm (#3) source
Example #4 source
dwd.pm (#4) source
dwd.conf source

CGI Scripting

Styling CGI Output - Example #2

The demonstration CGI program: Temperature Converter v1 shown so far was rather bland in appearance since no styling was included for simplicity, but on a real website that would never do.

If your website has a distinct visual theme or layout it is likely that you will want your CGI programs to match this and to be indistinguishable from the static pages.

It almost goes without saying that the output from your CGI program can contain whatever you want it to, and anything that would usually appear in a static page will work in the same way. Thus you need only add the required HTML and this will be achieved. But like most tasks there are many ways to do this and some are more effective than others!

In the webpage layout section a basic methodology was outlined for structuring a webpage, and also for using shared code in the form of external CSS and JS files as well as server-side includes (SSIs).

This handy method really comes into its own if we are also using dynamic CGI pages as these too can use these shared resources.

Generally speaking the main output for the dynamic page will be to the main page body; the header and footer will remain the same as the static pages, and the sidebars will be more or less the same although they may contain additional output from the CGI program.

So in essence all that you need do is add code to the program to achieve the following:

All of the extra page HTML can be output from the program using a simple print block:

print<<HERE;
[required html]
HERE

Streaming SSI Files

When Apache returns the output of CGI programs it does not parse them for server-side includes. However Perl itself can access the filesystem for you.

The solution here is to write a simple subroutine which will take the filename as an argument or parameter and directly output the content of the file with a print statement.

#  output_ssi:  Output from CGI programs goes straight to the browser,
#  it doesn't get parsed again by Apache and so server side includes
#  (SSIs) cannot be used. This function provides SSI functionality to
#  CGI scripts by writing the SSI file content into the output stream.
#  The expected argument is the required SSI file path.
sub output_ssi
  {my $file = "$_[0]";unless(($file) && (-r $file)) {return;}
  open(SSI,"$file") || die "Cannot open $file for read: $!";
  while(<SSI>) {print $_;}
  close(SSI) || die "Cannot close $file after read: $!";
  }

The advantage of doing this is that we can now share the head.ssi file which contains all of the shared CSS and JS for the website, all of this functionality now becomes instantly accessible to the dynamic pages as well.

I cannot emphasise enough how critical this technique can be for a large dynamic website. By making the dynamic programs share the same page layout and structure as the static pages these dynamic pages still retain the separation of style from content that makes global changes to the appearance of the website easy (to say nothing of possible in the first place!) The alternative is to hardcode a good deal of the page into the program, making changes a tedious task at best and very difficult if there are a lot of programs, or if the programs themselves are complex.

Using this method, the dynamic pages of your website become as easy to manage and maintain as the static ones!

We can apply this method to the previous example temperature calculator v1.

Click here to »view the v2 source code or here to »run the v2 program, both will open in separate windows.

The code is functionally the same as before, the only additions are the required top and bottom sections for the page which have been pulled out as separate subroutines for convenience and clarity, and the subroutine at the bottom which streams the SSI file into the output as described above.

The resulting page will match this one exactly, differing only in its content.

Note the use of $ENV{'DOCUMENT_ROOT'} which defines the path to the top-level directory of the website on the server. This is a CGI environment variable. All of the CGI environment is stored within the %ENV hash and available to CGI programs.

Within the code the names of the various SSI files have been hard-coded. For the purpose of this example this is fine, but not really good practice. In the next article we will start to look at ways to avoid issues such as this, and ways to share data amongst programs which make hard-coding unnecessary.

Show Style-Switcher...