Getting what the user typed in your form

Welcome back! I assume that you are tired of creating forms that just echo their input, per the previous lesson. In this lesson we are going to write a simple madlib program. This will allow us to explore how to retrieve the data the clients send us from our forms. To do more than just read this, you will need write access to a cgi-bin directory.

For this and further examples, I will be using the Perl. You can use any language in a cgi-bin program; I have just chosen perl. C examples will be added to this tutorial one day, when I get done with the perl ones.

To make your life easier, and to practice the famous computer adage of "Not reinventing the wheel", we will be using Steve Brenner's cgi-lib.pl script that turns messy, encoded form input into an associative array of keys and values. You will need to download this script and place it in your cgi-bin directory.

Now write a simple form that will request the following items, and store them in the variables named in ()'s:

Have your form call a script called madlib.pl in your cgi-bin directory. This means that a reference to madlib.pl should be placed in the action directive, similar to the way we used post-query in lesson one. My examples will call the madlib.pl program in my cgi-bin directory. Any form will do, mine, madlib.form.html, is listed below:

<html>
<head>
<link rev=made href="mailto:bex@ncsu.edu">
<title>Lets do a madlib!</title>
</head>
<body>

<h1>Please supply the requested items:</h1>

<hr>
<form method="POST" action="http://www.catt.ncsu.edu/cgi-bin/madlib.pl">
<UL>
<LI>A day of the week	<input name="day">
<LI>A person's name	<input name="name1">
<LI>Another person's name	<input name="name2">
<LI>A newsgroup name	<input name="newsgroup">
<LI>A noun		<input name="noun">
<LI>A verb		<input name="verb">
</UL>

<input type="submit" value="Punch me to see the MadLib"><BR>
<input type="reset" value="Use me to reset the screen">
</form>

<hr>
<P><img src="/pix/paws/blue.gif" alt=" * ">Comments to Brian Exelbierd
(<a href="../tutor.mail.html">bex@ncsu.edu</a>)<BR>
<img src="/pix/paws/green.gif" alt=" * ">
To the front of the <a href="../index.html">tutorial</a>.<BR>
<img src="/pix/paws/red.gif" alt=" * ">
To bex's <a href="/~bex/index.html">home page</a>
on the <a href="/index.html">CATT</a> WWW Server</P>
</body>
</html>

If you use your browser to display the file you just created, you will notice that it looks just like a functional form. Well, looks are deceiving, because it currently won't work. This is because the form is just the front end to the actual processor, the script.

Now we need to write the script. The script should do only one thing, return proper html with the blanks of the madlib filled in with the things the user typed. Basically this is a set of print statements in perl. The following will guide you through the perl script:

You should name your script descriptively based on what it does. For this example let's use the name madlib.pl to denote a script that makes a madlib, and is written in perl.

  1. On the first line, you need to tell your shell how to run perl on your system. This is typically done with a line that tells the shell where perl is and to execute it. An example is:
    #!/usr/local/bin/perl
    

    You can typically find perl on your system by typing which perl.

  2. Contrary to popular belief, comments are nice, and help people understand what is going to happen. In perl a comment starts with a # symbol. The comments should include:
    One fine day, name1 was reading newsgroup, and noticed a post where name2 asked for help making their noun verb.

    A set of comments might look like this:

    # madlib.pl
    # By Brian Exelbierd (bex@ncsu.edu) 1-1-95
    #
    # This program accepts www form input and produces the following madlib
    # One fine _day_, _name1_ was reading _newsgroup_, and noticed a post where
    # _name2_ asked for help making their _noun_ _verb_.
    #
    # This program uses Steve Brenner's cgi-lib.pl library to handle the input
    
  3. Before we can use Steve's library, we have to tell perl to include it and where to find it. We include with the require statement, and we tell perl how to find it by adding to the variable @INC. @INC is really just a list of paths (relative to the file system, not the web) of where to look for libraries. For more information on this see PERL -- Practical Extraction and Report Language. The lines should look like this (substitute the path to your cgi-bin for mine):
    push(@INC,"/p/www/httpd/cgi-bin");
    require("cgi-lib.pl");
    
  4. Now we need to get the input from the user. Thanks to Steve and his cgi-lib.pl library, we only have to call the ReadParse subroutine. It will return us all the user input in an associative array, called in, which is keyed by variable name. This means we can ask for the value of a variable just by knowing the name of the variable. To call subroutines in perl, we just prepend the name of the subroutine with an ampersand (&), like this:
    &ReadParse;
    

    The semicolon is very important. All perl statements must end in a semicolon.

    Note: The & is not strictly required in perl5.

  5. Now that we have the input, we need to print out the madlib. Before we can do that though, we have to print out the line to tell the client that what follows is html code. Steve has again provided a function to help us do that in his cgi-lib.pl library. The function is called PrintHeader, and to print in perl you just use the print statement, followed by what you wanna print. You do have to enclose strings in quotes, and separate items with commas though. In order to print a quote (") symbol you would need to escape the quote so it is not interpreted as one of the quotes surrounding the stuff to be printed. In order to escape the quote you simply precede it with a backslash (\). i.e. \" To print the header, we can just type this:
    print &PrintHeader;
    
  6. Ok, let's print out the html code that occurs before the first line of the madlib. Remember, we have to quote strings, and html does not make a line break, unless it sees a paragraph or linebreak marker. To make our output more human-readable though, we probably want to break it up with new lines between significant elements. To print a new line in perl, print the string "\n". My code looked like this:
    print "<HTML>\n";
    print "<HEAD>\n";
    print "<TITLE>A madlib</TITLE>\n";
    print "</HEAD>\n";
    print "<BODY>\n";
    print "\n";
    print "<H1>Here it is:</H1>\n";
    print "\n";
    
  7. Now we need to learn to reference our variables correctly so we can print them. Our input is stored in an associative array called in. We know that it is stored/keyed by variable name. In perl you just use the following syntax to print an associative array value.
    $array_name{'key_name'}
    

    For example printing a variable called foo from the in array looks like this:

    $in{'foo'}
    

    To print text around the variable, just type it in quotes around the variable reference, like this:

    print "We are about to reference a variable. ",$in{'variable'},", fun huh?\n";
    

    The trailing new line, while not needed, will make the source more readable if someone tries to view it. My code follows:

    print "<P>One fine ",$in{'day'},", ",$in{'name1'}," was reading\n";
    print $in{'newsgroup'}," and noticed a post where ",$in{'name2'}," asked for\n";
    print "help making their ",$in{'noun'}," ",$in{'verb'},"</P>\n";
    

    Note: You can print variables within strings so that you don't have to put all the commas in. It is your choice. An example of printing the variable $foo preceded by the word "the" and followed by the words "is blue" is:

    print "The $foo is blue";
    

    Fairly simple huh?

    One thing to note is that if you print textarea variables, they will not appear to be separated into lines like they were input. Remember that html does not break lines except at <P> and <BR> tags. The following piece of perl code will put a linebreak in for every new line. It can easily be made to do paragraph breaks.

    $variable =~ s/\n/<BR>\n/g;
    
  8. The only thing we have left to do is to finish the html code, and then test it. My complete script follows, but try yours out to make sure it works. Remember you need to put your script into the cgi-bin directory.
    #!/usr/local/bin/perl
    # madlib.pl
    # By Brian Exelbierd (bex@ncsu.edu) 1-1-95
    #
    # This program accepts www form input and produces the following madlib
    # One fine _day_, _name1_ was reading _newsgroup_, and noticed a post where
    # _name2_ asked for help making their _noun_ _verb_.
    #
    # This program uses Steve Brenner's cgi-lib.pl library to handle the input
    
    push(@INC,"/p/www/httpd/cgi-bin");
    require("cgi-lib.pl");
    
    &ReadParse;
    
    print &PrintHeader;
    
    print "<HTML>\n";
    print "<HEAD>\n";
    print "<TITLE>A madlib</TITLE>\n";
    print "</HEAD>\n";
    print "<BODY>\n";
    print "\n";
    print "<H1>Here it is:</H1>\n";
    print "\n";
    
    print "<P>One fine ",$in{'day'},", ",$in{'name1'}," was reading\n";
    print $in{'newsgroup'}," and noticed a post where ",$in{'name2'}," asked for\n";
    print "help making their ",$in{'noun'}," ",$in{'verb'},"</P>\n";
    
    print "</BODY>\n";
    print "</HTML>\n";
    

You can also access any environment variables by getting them by name from the associative array ENV. To get an idea of what environment variables are set, use the test-cgi script. The source for this shell script is distributed with NCSA HTTPD, and is authored by them, not me.


 * Comments to Brian Exelbierd (bex@ncsu.edu)
 * To the next How do I append to a non-html file? (joke-submission example)
 * To the front of the tutorial.
 * To bex's home page on the CATT WWW Server

HTML 2.0 Checked! Last Updated and Validated on February 6, 1996