Software, your way.
burger menu icon
WillMaster

WillMaster > LibraryTutorials and Answers

FREE! Coding tips, tricks, and treasures.

Possibilities weekly ezine

Get the weekly email website developers read:

 

Your email address

name@example.com
YES! Send Possibilities every week!

Writing Your Own Form Handling Scripts (Perl CGI), Part III

Todays' article is the third of four installments. Here is a table of contents for the entire series:

  1. How to put information from the form into the script.
  2. How to store the form information in a database file on your server -- in any plain text format, including tab- and comma-delimited formats that can be imported into Excel and other spreadsheet and database programs.
  3. How to send the form information to yourself in an email -- formatted however you please, including HTML.
    1. The example form and the script.
    2. The email template.
    3. Sending the email.
    4. The script up to this point.
  4. How to personalize the "thank you"/confirmation page for your form user.

If you haven't read Parts I and II of this tutorial, do so now. They are linked from the Willmaster Library index.

III. How to send the form information to yourself in an email -- formatted however you please, including HTML.

a. The example form and the script.

Retrieve the example form and script from the "Writing Your Own Form Handling Scripts, Part II" linked at the Willmaster Library index.

The script, with today's modifications incorporated, is also printed at the end of this article.

b. The email template.

The first thing to do is create an email template file. The template will be the outgoing email's format with placeholders where the script will insert form information before sending the email.

Placeholders for email templates are the same as for database templates, form field names enclosed with double square brackets. Here is an example email template:

From: "[[username]]" <[[email]]>
To: "Your Name" <email@domain.com>
Cc: "Another Name" <another@domain.com>
Bcc: a@domain.com, b@domain.com, c@domain.com
Subject: [[Subject]]

The form has been submitted with the following information:

Name:           [[username]]
Email:          [[email]]
Gender:         [[gender]]
Favorite Color: [[favorite color]]
Color List:     [[c2]]
Message:
[[message]]

A few notes about the above email template:

  1. The first lines of the template are the header lines of the outgoing email.
     
  2. A minimum header is the "To:" line. The rest in the example are optional.
     
  3. The sequence of the header lines doesn't matter.
     
  4. If you want to send HTML email, add the following two lines to the header:

Mime-Version: 1.0
Content-Type: text/html; charset="iso-8859-1"

  1. There must be a one blank line between the header lines and the email body, and it must be the first blank line in the file.

The email body can have placeholders for any or all of the form information, or even none if you just want to send a "thank you" email (in which case the "To:" header line would have the form user's email address).

c. Sending the email.

Near the top of the script, insert these two lines:

my $EmailTemplateFile = 'template.txt';
my $Mailer = '/sbin/sendmail -t';

The $EmailTemplateFile variable holds the file name of the email template you created above. The file should be uploaded into the same directory as the script.

The $Mailer line holds the location of your sendmail or qmail. If sendmail, include the -t flag. Either sendmail and qmail are almost always found on UNIX/Linux servers. The emailing subroutine below will send email only if one of those two are present on the server.

Put this emailing subroutine at the bottom of your script:

sub SendEmail
{
   open R,$EmailTemplateFile;
   my $email = join '',<R>;
   close R;
   for(keys %In) { $email =~ s/\[\[$_\]\]/$In{$_}/sig; }
   $email =~ s/\[\[.*?\]\]//sig;
   open MAIL,"|$Mailer";
   print MAIL $email;
   close MAIL;
} # sub SendEmail

The first three lines retrieve your email template. The next two lines replace the placeholders with form information. And the last three lines send the email.

To use the SendEmail subroutine, your statement would be:

&SendEmail;

Put the statement immediately below the &UpdateDatabase; statement mentioned in the section II.

d. The script up to this point.

Here is the form handling script up to this point:

#!/usr/bin/perl
# By [your name here]
use strict;

my $AuthorizedDomain = 'mydomain.com';
my $DBtemplate = "[[username]]\t[[email]]\t[[message]]\n";
my $DatabaseFile = 'data.txt';
my $EmailTemplateFile = 'template.txt';
my $Mailer = '/sbin/sendmail -t';

my %In = ();
my $FormDomain = lc $ENV{HTTP_REFERER};
$FormDomain =~ s!^https?://(?:www\.)?(.*?)(?:/.*)$!$1!;
unless($FormDomain eq lc $AuthorizedDomain)
   { ErrorHTML('Unauthorized access.'); }
unless(ParsePost())
   { ErrorHTML('Unauthorized access.'); }
unless($In{email})
   { ErrorHTML('An email address is required.'); }
unless(ValidEmail($In{email}))
   { ErrorHTML('Sorry, invalid email address format.'); }
if(length($In{message}) > 250)
   { $In{message} = substr($In{message},0,250); }

&UpdateDatabase;
&SendEmail;

ErrorHTML('Script paused here.'); # temporary line

Exit();

sub ParsePost
{
   return 0 unless $ENV{REQUEST_METHOD} =~ /POST/i;
   my $buffer;
   read(STDIN,$buffer,$ENV{CONTENT_LENGTH});
   my @p = split(/&/,$buffer);
   foreach(@p)
   {
      $_ =~ tr/+/ /;
      my ($n,$v) = split(/=/,$_,2);
      $n =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
      $v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
      $v =~ s/(\<.*?)(embed|object|script|applet)(.*?\>)/$1$3/gis;
      if($In{$n}) { $In{$n} .= "\t$v"; }
      else { $In{$n} = $v; }
   }
   return 1;
} # sub ParsePost

sub ValidEmail
{
   if($_[0]=~/([\.\-\_]{2,})|(@[\.\-\_])|([\.\-\_]@)|(\A\.)/)
      { return 0; }
   if($_[0]=~/^[\w\.\-\_]+\@\[?[\w\.\-\_]+\.([\w\.\-\_]{2,3}|[0-9])\]?$/)
      { return 1; }
   return 0;
} # sub ValidEmail

sub ErrorHTML
{
   my $s = join("\n<li>",@_);
   print "Content-type: text/html\n\n";
   print <<HTML;
<html><body bgcolor="white">
<blockquote><blockquote>
<h4>Message:</h4>
<ul>
<li>$s
</ul>
</blockquote></blockquote>
</body></html>
HTML
   Exit();
} # sub ErrorHTML

sub Exit { exit; }

sub MakeOneLine
{
	my $s = shift;
	my $replacement = '<br>';
	if($s =~ /\n/) { $s =~ s/\r//gs; }
	else { $s =~ s/\r/\n/gs; }
	$s =~ s/\n/$replacement/gs;
	return $s;
} # sub MakeOneLine

sub ConvertTabValueSeparaters
{
	my $s = shift;
	my $replacement = ' -- ';
	$s =~ s/\t/$replacement/gs;
	return $s;
} # sub ConvertTabValueSeparaters

sub GetFormattedDate
{
	my @Weekday = qw(
		Sunday 
		Monday 
		Tuesday 
		Wednesday 
		Thursday 
		Friday 
		Saturday);
	my @Month = qw(
		January 
		February 
		March 
		April 
		May 
		June 
		July 
		August 
		September 
		October 
		November 
		December);
	my ($sc,$mn,$hr,$mday,$mon,$yr,$wday,$yday,$dst) = localtime;
	$yr += 1900;
	return "$Weekday[$wday], $Month[$mon] $mday, $yr";
} # sub GetFormattedDate

sub GetFormattedTime
{
	my ($sc,$mn,$hr,$mday,$mon,$yr,$wday,$yday,$dst) = localtime;
	my $s = '';
	$s .= $hr < 10 ? "0${hr}:" : "${hr}:";
	$s .= $mn < 10 ? "0${mn}:" : "${mn}:";
	$s .= $sc < 10 ? "0${sc}"  :  $sc;
	return $s;
} # sub GetFormattedTime

sub UpdateDatabase
{
   my $t_message = $In{message};
   my $t_c2 = $In{c2};
   $In{message} = MakeOneLine($In{message});
   $In{c2} = ConvertTabValueSeparaters($In{c2});
   $In{Date} = &GetFormattedDate;
   $In{Time} = &GetFormattedTime;
   for(keys %In) { $DBtemplate =~ s/\[\[$_\]\]/$In{$_}/i; }
   $DBtemplate =~ s/\[\[.*?\]\]//i;
   if(-e $DatabaseFile) { open W,">>$DatabaseFile"; }
   else { open W,">$DatabaseFile"; }
   print W $DBtemplate;
   close W;
   $In{c2} = $t_c2;
   $In{message} = $t_message;
} # sub UpdateDatabase

sub SendEmail
{
   open R,$EmailTemplateFile;
   my $email = join '',<R>;
   close R;
   for(keys %In) { $email =~ s/\[\[$_\]\]/$In{$_}/sig; }
   $email =~ s/\[\[.*?\]\]//sig;
   open MAIL,"|$Mailer";
   print MAIL $email;
   close MAIL;
} # sub SendEmail

The "Script paused here." message in the above code will be removed when the script is completed.

Part IV of this series shows you how to take the information in the %In variable and create custom "thank you" pages.

See you then :)

Will Bontrager

Was this article helpful to you?
(anonymous form)

Support This Website

Some of our support is from people like you who see the value of all that's offered for FREE at this website.

"Yes, let me contribute."

Amount (USD):

Tap to Choose
Contribution
Method

All information in WillMaster Library articles is presented AS-IS.

We only suggest and recommend what we believe is of value. As remuneration for the time and research involved to provide quality links, we generally use affiliate links when we can. Whenever we link to something not our own, you should assume they are affiliate links or that we benefit in some way.

How Can We Help You? balloons
How Can We Help You?
bullet Custom Programming
bullet Ready-Made Software
bullet Technical Support
bullet Possibilities Newsletter
bullet Website "How-To" Info
bullet Useful Information List

© 1998-2001 William and Mari Bontrager
© 2001-2011 Bontrager Connection, LLC
© 2011-2024 Will Bontrager Software LLC