Mike Gossland's Perl Tutorial Course for Windows


Intro to CGI | First Page | Printing HTML | Serving HTML | Serving Edited


Chapter 5. Introduction to CGI

Printing HTML

We've seen the print statement in action in earlier lessons. You can print anything you like in HTML with a sequence of print statements. This was the technique used in previous script — specifying one print statement after another. As long as you begin by printing the correct Content-Type and a blank line, you will have no problem.

Let's look at a couple of alternatives to repeated print statements because there are easier ways. Let's quote the whole thing within a single variable and just print once:

$html = "Content-Type: text/html

<html>
  <head>
    <title>hello World</title>
  </head>
  <body>
    <h4>hello World</h4>
    <p>
      Your IP Address is $ENV{REMOTE_ADDR}
    <p>
    <h5>have a nice day</h5>
  </body>
</html>";

print $html;

This is easier because of two things. We don't have to keep track of quotes around as many strings, and we can let the new lines within the block itself specify the \n characters.

But now that we're quoting, suppose we wanted to put the word nice into quotation marks? If we wrote:

<h5>Have a "nice" day</h5>

in the original script, we'd get a syntax error, because the two quote marks we put in would match with the opening and closing quotes already there. The solution is to backquote the new ones, like this:

<h5>Have a \"nice\" day</h5>

This takes away the syntax error since the quotes are interpreted as part of the string itself. Sometimes though, this backquoting gets to be too much of a pain when there a lots of quotes such as in the next example. In that case, you can use a different quoting delimiter, and use the explicit quoting operator, qq{}.

$html = qq{Content-Type: text/html

<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
    <h4>Hello World</h4>
    <p>
      Your IP Address is $ENV{REMOTE_ADDR}
    <p>
    <h5>Have a "nice" day</h5>
    <p>Name:<input type="text" size="20" name="txt_name" value="name">
  </body>
</html>};

print $html;

See how much nicer looking it is when you don't have to backquote the quotes? Like s///, the quote operator qq provides you with a complete choice of delimiters, so you can just choose one that doesn't collide with your quoted text.

Just so you've heard of it, you can also use the "here document" form of printing. "Here documents" originate in Unix shell programming and they have been incorporated into Perl. With qq's ability to quote over newlines, I'm not sure what advantage they offer. In any case, here's an example:

print <<EOF;
Content-Type: text/html

<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
    <h4>Hello World</h4>
    <P>
      Your IP Address is $ENV{REMOTE_ADDR}
    <p>
    <h5>Have a "nice" day</h5>
    <p>Name:<input type="text" size="20" name="txt_name" value="name">
  </body>
</html>
EOF

The "here document" always follows the form:

print <<TAG;
...
TAG

It is an alternative to the quotation operator. It is very important that your closing TAG be right up against the left margin with no preceding space, or it won't work right.

These previous examples are very simple since they just print out an explicit string of html. But face it, there'd be little point in using Perl to serve up static content like that. Perl begins to be useful in the role of serving content when you make up the output with your program, like this example of code to print a table of squares. In this example, we are defining two control parameters, $title and $rows, at the top in a couple of global variables, and we use two functions to provide the head and body content of the HTML.

(Caution: global variables are not recommended once you are no longer a beginner. There's too much potential for inadvertently changing their values, so don't do it all the time. You've been warned.) 

$title = "Table of Squares";
$rows=10;

print "Content-Type: text/html\n\n";

print header();
print body();

sub header() {

  return qq{<HTML>\n<HEAD>\n<title>$title</title></head>};

}

sub body() {
  $body = qq{
    <body>
    <div align="center">
    <h4>$title</h4>
    <p>
    <table border="1">
  };

  for $i ( 1 .. $rows ) {
    $body .= qq{<tr><td>Row $i</td>};
    $body .= qq{<td width="50" align="center">};
    $body .= $i*$i;
    $body .= qq{</td></tr>\n};
  }

  $body .= qq{
    </table>
    </div>
    </body>
    </html>
  };

  return $body;
}

These examples demonstrate Perl's ability to generate HTML on the fly. As powerful as it is, there is a disadvantage in this approach. The technique mixes your HTML coding tightly within your Perl programming. It is generally a good design idea to try to keep each area separate, because you can approach the project either as an HTML author, or as a Perl programmer. So can other people you bring in to work on your project.

In the next section we'll look at serving HTML files that have been authored outside of Perl.