Basic elements of Perl and Python. Simple CGI scripts that keep state. Last time we learned about posting an HTML page on your web server.
All HTML files need to be somewhere under htdocs (which is called the DocumentRoot of your web server).
So if you have one.html in a folder two of htdocs you access it like this:
http://silo.cs.indiana.edu:[port]/two/one.html
Notice that you don't ever mention htdocs on the URL. CGI scripts have a folder of their own in which they need to reside:
~/apache/cgi-bin/ (also known as ScriptAlias)CGI scripts need to be located somewhere below this folder.
So if you have a script nine in a folder six in a folder three in cgi-bin:
http://silo.cs.indiana.edu:[port]/cgi-bin/three/six/nine
The URL above is how you call the script. Note the script alias appears in the URL. CGI means Common Gateway Interface. It is a set of conventions.
Today we are going to summarize the essence of these conventions, in an operational way.
1. HTML Forms
Let's build an interface in HTML:
<html>
<head><title>some title</title></head>
<body>
<form>
Type your name here: <input type="text" name="name"> <p>
Indicate your age: <input type="text" name="age"> (in years). <p>
Press <input type="submit" name="submit" value="this button"> to continue.
</form>
</body>
</html>
Put this in htdocs and type something in: lbird, 51. Then push the button. What happens? The URL changes to this for me:
http://silo.cs.indiana.edu:9306/one.html?name=lbird&age=51&submit=this+button
The data is collected from the form's fields and are being sent on the URL. The format name=value&name=value&... is much of what CGI is.
CGI is a set of conventions on how the data is to be collected and passed to the called program/script.
So the purpose of a form is to collect data from the end user.
The HTML form can specifically indicate a URL where the collected data should be sent.
Let's modify our form as follows:
<form action="/cgi-bin/eight">In other words we make only one change, add an action attribute to the form tag.
This indicates that the data collected needs to be sent:
When this attribute is missing a default URL value is used: the file that contains the form itself.
Let's write a script called eight:
This script collects, parses and prints all the data that comes in.#!/usr/bin/perl use CGI; $q = new CGI; print $q->header, $q->start_html; print $q->Dump; print $q->end_html;
2. Input Data in CGI Scripts (Perl).
Now let's make the script print the form itself.
We have to be careful to put everything in the right way.
First off, if the form is printed by the script the action attribute is not necessary any longer.
If the script is called by typing its URL no data will be sent to it.
In that case the Dump method will print nothing.
The script can then print the form.
Here's what we get:
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
print $q->Dump;
print qq{
<form>
Type your name here: <input type="text" name="name"> <p>
Indicate your age: <input type="text" name="age"> (in years). <p>
Press <input type="submit" name="submit" value="this button"> to continue.
</form>
};
print $q->end_html;
The use of print qq{ } is similar to that of print " "; qq{ in conjunction with }; act just like " in conjunction with ";
qq means quote quote (double quote) so it's easy to remember.
qq{ ... } can span multiple lines. " ... " also, but we should not count on it.
qq{ " } is equivalent to "\"" so some simplifications are allowed.
Let's replace the Dump call (which is too general) with a more customized action.
If the user types lbird for the name, and 51 for the age, the program should write back:
Hello, lbird! Next year you will be 52!In other words we need to get our hands on the name, and the age.
Then put together a reply as indicated.
The name is available via
$q->param("name");
The age is available via
$q->param("age");
The script would then use them accordingly, to become:
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
$name = $q->param("name");
$age = $q->param("age");
$nextYear = $age + 1;
print qq{
Hello, $name! Next year you will be $nextYear years old. <p>
<form>
Type your name here: <input type="text" name="name"> <p>
Indicate your age: <input type="text" name="age"> (in years). <p>
Press <input type="submit" name="submit" value="this button"> to continue.
</form>
};
print $q->end_html;
Now that we have seen this let's write a simple Perl program to be used at the prompt. 3. Basic Perl.
We'll develop this program:
#!/usr/bin/perl
%contents = ("snickers" => 70, "pretzels" => 50, "soda" => 75);
print "Welcome to the vending machine!\nready> ";
while ($input = <STDIN>) {
chop($input);
if ($input eq "quit") { last; }
elsif ($input =~ /^add\s/) {
($add, $what, $price) = split(/ /, $input, 3);
$contents{$what} = $price;
} elsif ($input =~ /^\s*show\s+all\s*$/i) {
foreach $key (keys %contents) {
$price = sprintf("%4.2f", $contents{$key} / 100);
print $key, " --> \$", $price, "\n";
}
} elsif ($contents{$input}) {
$price = sprintf("%4.2f", $contents{$input} / 100);
print $input, " costs \$$price\n";
} else {
print "I don't understand $input, sorry.\n";
print "Try: show all, add <product> <cents>, <product>, or quit\n";
}
print "ready> ";
}
We'll discuss this program in detail. We'll also develop a simple calculator:
#!/usr/bin/perl
$balance = 0;
print "Your balance is: $balance\n";
print "Type> ";
while ($line = <STDIN>) {
chop($line);
($fun, $arg) = split(/ /, $line, 2);
print "You want to $fun a value of $arg to the balance of $balance.\n";
if ($fun =~ /^add/i) {
$balance += $arg;
} elsif ($fun =~ /^sub/i) {
$balance -= $arg;
} else {
print "I am sorry I don't understand $fun.";
}
print "The balance is now: ", $balance, "\n";
print "Type> ";
}
This program is simpler, its discussion will help us reinforce the concepts introduced previously. Now the question is: how can we implement this in a web script?
3. Perl/CGI Scripts that Keep State.
We will discuss this program:
#!/usr/bin/perl
use CGI;
$q = new CGI;
print $q->header, $q->start_html;
$count = $q->param('count') + $q->param('add') + 0;
print qq{
<table border cellpadding=2>
<tr><td colspan=2 align=center> <h1>$count</h1>
<tr><td width=50% align=center> <a href="?count=$count&add=-1">Down</a> <td> <a href="?count=$count&add=1">Up</a>
</table>
};
Our simple challenge for the week will be to rewrite this. The requirement is to replace links with submit buttons (in forms).
As we will see, that's quite easy. We'll even do it together in class.
4. Python
Here we just review Python from the point of view of the Perl we cover.
Check the following tutorial notes:
http://www.cs.virginia.edu/~lab2q/lesson_1/
We will base our development in class (second part of Thu's lecture) on this tutorial. We will develop/design what we want, but in the process we will refer to the tutorial.
Python and CGI processing information (as implemented in Python) is what we will look up.