CGI is not a language: it is an input/output protocol for communicating via the WWW.
Unlike SSI, PHP or ASP, CGI code is not embedded in an existing html document,
it is actually a method for generating web pages from scratch, on the fly.
The script accomplishes this by printing the raw HTML code that the browser
expects to standard out.  The web server redirects the script's standard out to the
browser, which behaves as if the data came from a regular .html file.

CGI.pm is a Perl Module available on CPAN that offers convenient shortcuts for
generating the html that will be sent to the calling browser.  This document
explains the use of the CGI.pm shortcuts for generating on-the-fly web content.

To activate a CGI script, put it in your server's "cgi-bin" directory as executable
by the server userid (on Unix systems this is generally user "nobody").  Check your
server's documentation for instructions on how to enable CGI on your system.

To access a CGI script from the web, point a link at the program itself.
Click here for the companion demo.

CGI-generated forms automatically call the script which generated them with the data
you've supplied, so you need to check whether data has been submitted to determine
if this is the user's first trip to the page or not.  See the "if ( param )" block
of the basic-form.pl script supplied below to see how to process user-supplied data.


BASIC FORM EXAMPLE (for Unix)
----------------------------------
#!/usr/local/bin/perl -w
#
#       basic-form.pl   -       A skeleton form example
#
#       -w means "warn me about nitpicky little problems"
#
use strict;				# Forbid me from doing insecure/stupid things
use CGI qw(:standard);			# Use the standard methods of CGI.pm module

print					# Displaying CGI methods are driven via print
  header,				# Tell browser this is html data
  start_html("Basic Form Example"),	# Start page itself and supply title
  start_form,				# Begin form (or form elements won't display)
  "Enter your name: ",			# Prints this phrase to the page
  textfield("name"),			# Creates an empty text box called "name"
  submit,				# Submit button to send form data to server
  reset,				# Reset button to clear values from form
  end_form,				# End form
  hr;					# Horizontal rule to divide form from results

					# If users supplied any values, then display
if ( param )				# "param" contains existing name/value pairs
{
  my $value = '';			# Define variable to hold parameter values
  print h1("Parameters supplied by user");	# Print text in 1st header style
  foreach ( param )			# Process each parameter stored in param
  {
    $value = param("$_");		# Save value of parameter in $value
    print b("$_ => $value");		# Print "name => bob", etc, in bold type
    print br;				# Send line break between each item returned
  }

  my $environ = '';			# Define variable to hold environment values
  print h1("Environment variables");	# Print text in 1st header style
  foreach ( sort keys %ENV )		# Process each environment variable found
  {
    $environ = $ENV{"$_"};		# Save value in variable $environ
    print b("$_ => $environ");		# Print "USER_AGENT => mozilla", etc in bold
    print br;				# Send line break between each item returned
  }
}

print
  end_html;				# Alert browser this is the end of html data

exit;					# Quit the program





ACCESSING CGI.pm SHORTCUTS
use CGI qw(:standard :html3);		# :html3 is for the table elements


OUTPUT (generating web pages)
----------------------------------
(to implement these, put in a print statement)

Structural elements
header
start_html("Page title goes here")
end_html
redirect("http://www.perl.com")

Formatting tags
b("bold text")				# <B>bold text</B>
i("italic text")			# <I>italic text</I>
strong("strong text")			# <STRONG>strong text</STRONG>
h1("Header type 1")			# <H1>Header type 1</H1>
h2("Header type 2")			# <H2>Header type 2</H2>
h3("Header type 3")			# <H3>Header type 3</H3>
hr					# <HR>
p("paragraph")				# <P>paragraph</P>
br					# <BR>
comment("comment")			# <!-- comment -->
ul( li( {-type => "disc"}, ['first','second','third'] ) )
					# <UL>
					#  <LI TYPE="disc">first</LI>
					#  <LI TYPE="disc">second</LI>
					#  <LI TYPE="disc">third</LI>
					# </UL>

Form elements
NOTE: when a form is re-displayed, any values stored in param from previous viewing
will be supplied as defaults, overriding any -default option supplied

# Assume this has been declared for all form examples
%labels	= (	'first'  => 'option 1',
			'second' => 'option 2',
			'third'  => 'option 3',
			'fourth' => 'option 4');

start_form("form_name")			# Name is optional
end_form
textfield(	-name => 'textfield_name',
			-default => "starting_value",
			-size => 30,
			-maxlength => 50)
textarea(	-name => 'textarea_name',
			-default => "starting_value",
			-rows => 4,
			-columns => 20)
password_field(-name => "password_field_name",
			-size => 10,
			-maxlength => 20)
popup_menu(	-name => "popup_menu_name",
			-value => ['first','second','third','fourth'],
			-default => 'first',
			-labels => \%labels)
scrolling_list(-name => "scrolling_list_name",
			-value => ['first','second','third','fourth'],
			-default => ['second'],
			-size => 3,
			-multiple => 'true',
			-labels => \%labels)
checkbox_group(-name => "checkbox_group_name",
			-value => ['first','second','third','fourth'],
			-default => ['third'],
			-linebreak => 'true',
			-labels => \%labels)
checkbox(	-name => "checkbox_name",
			-value => 'ON',
			-checked => 'checked',
			-label => 'CLICK ME')
radio_group(	-name => "radio_group_name",
			-value => ['first','second','third','fourth'],
			-default => 'fourth',
			-linebreak => 'true',
			-labels => \%labels)
submit(		-name => "submit_name",
			-value => "submit_value)
reset		# set elements to their values when the form displayed THIS TIME
defaults	# set elements to their values when the form displayed INITIALLY
hidden(		-name => "hidden_name",
			-value => "hidden_value")

Table elements
print table
	(
		{ -border => 1, -width => "100%" },
		caption("This caption runs across the top of the table"),
		Tr
		(
			{ -align => CENTER, -valign => TOP },
			[
				th(['header 1','header 2','header 3']),
				td(['row 1, col 1','row 1, col 2','row 1, col 3']),
				td(['row 2, col 1','row 2, col 2','row 2, col 3']),
				td(['row 3, col 1','row 3, col 2','row 3, col 3']),
			]
		)
	);


INPUT (handling form data)
----------------------------------

Environment variables
$ENV{"environment_variable_name")	# works for any environment variable
user_agent()				# Browser identification string
referer()				# Page browser was viewing prior to script
					# (this value can be hacked!)
remote_user()				# UserID from server authorization
					# (undef if no auth performed)
request_method()			# GET, POST or HEAD
					# Who cares? Both are handled transparently

Form values
param("foo")				# Returns value of parameter foo
param("foo",$foo_value)			# Sets value of parameter foo to $foo_value
delete("foo")				# Removes parameter foo from system
delete_all()				# Clears parameter list