Saveform 3.02a

This is an alpha program. Use at your own risk!

Why Saveform?

So, you want to add forms to your website, but don't have the time/ability/inclination to write software to handle them?

Perhaps Saveform can help.

Saveform is a WWW form proccessing tool that is designed to run in either DOS, Windows or UNIX, and to be highly powerful and extensible, while remaining very easy to use. And, it's freeware!

There are other programs out there which aim to let you write a form, plug in the program, and forget about it. However, all I've seen handle one very specific purpose, such as sending an email, or saving a user's comments. Most of these programs have a inflexible output style as well.

I've configured Saveform to:


First, download the saveform package.

You should get 2 files --, and saveform.cfg. Copy both these files to a directory your web server can run cgi scripts from.

To run Saveform, you will need perl 5.0 or above. You may need to edit the first line of to point to the location of the perl program.

Saveform has several items that need to be configured. These are located in the saveform.cfg file. The most important part of this file is the "mydir=" line. This specifies a directory Saveform uses for its datafiles. For security, this directory should contain only Saveform datafiles, and should have no directories under it. Make a directory for this purpose, and set the "mydir=" line to point to it.

Setting up Saveform -- A quick tutorial

Saveform uses two types of datafiles. The first, "runfiles" are lists of commands that tell Saveform what to do. The second, "templates", are files that are used to format Saveform's output. Both types of files go in the datafile directory you specified when you installed Saveform. This section of the documentation will guide you through setting up the runfiles and templates needed by a simple use of Saveform.

Let's set up a simple comments form that saves the message to a log of messages. First, the HTML form that calls Saveform will look like this:

From:<INPUT TYPE="text" NAME="name"><P>
Email:<INPUT TYPE="text" NAME="email"><P>
Subject:<INPUT TYPE="text" NAME="subject"><P>
To submit your message, press this button: 
<INPUT TYPE="submit"VALUE="Submit Comments">
All you need to do is change the "/cgi-bin/" to whatever will make your web server run saveform, and put the page up on your server.

Now, we need to tell saveform how to handle this form. All it really has to do is append the form to the end of a file, and then display a message to the user to let them know that their comments have been recieved.

As the first step in doing this, let's create two templates. Save them both to the directory you told Saveform to use for its datafiles. This one generates a message to the user, letting them know that everything's been taken care of. Save it as "comments.ok".

<H1>Your comments have been saved.</h1>
Thanks for your comments, ~name~. They have been saved, and I will take a look 
at them soon. 
Notice the "~name~" tag in this template? That will be replaced by whatever they fill in on the text control called "name" on the form.

The second template is appeneded to the comments file, to save their comments. Save it as "comments.sav".

Name: ~name~
Email: ~email~
Subject: ~subject~
Notice that this template has several tags, like "~name~", and "~email~" each of these tags is replaced by whatever is entered on the corresponding control on the form.

Finally, we have to write the runfile that tells Saveform what to do with these files. Save this runfile as "":

append comments.sav /comments/comments.dat
return comments.ok
This simple little runfile appends comments.sav to /comments/comments.dat, and then returns the comments.ok template to the user.

With the creation of this runfile, everything should be ready to go. Just create a directory named /comments/ (or change the runfile to use a different directory), and create a comments.dat file so there is a file for Saveform to append to. If you are on a unix system, make sure that comments.dat can be written to by the web server.

Give it a try.. Once you get it working, try editing the templates to customise the output to your liking.

Now, the sample template and runfiles I showed you are simple, and easy to understand. The one downside is that if you have many runfiles, each using make templates, you can end up with lots and lots of files and a cluttered Saveform data directory. Saveform has a feature which moves the templates into the runfiles, so you have just one Saveform file per form.

Here is, rewritten to use that feature:

append /comments/comments.dat [
	Name: ~name~
	Email: ~email~
	Subject: ~subject~
return [
	<H1>Your comments have been saved.</h1>
	Thanks for your comments, ~name~. They have been saved, and I will take a look
	at them soon.
As you can see, the two templates are now in the runfile, enclosed in brackets. The deatils of this will be explained later., but note that you have to put a tab before each line of a template that is "inlined" in this way.

Setting up a form to use Saveform

To get Saveform to process a form, that form has to call when it is posted.

For DOS or Windows, a form that uses Saveform should be defined like this: (Be sure to uncomment the "dos=yes" line of saveform.cfg.)

<FORM METHOD="POST" ACTION="dir/perl.exe/">
                            |-----a----| |-----b----| |-----c--------|       
For a UNIX system, use something like this:
                            |------d------| |-----b----|
a:Path to perl.
b:Runfile to use.
c:Path to

Setting Up Runfiles

The runfile is a text file that lists commands for to perform. Commands should go one after the other, each on its own line. Commands are not case sensative.



Setting up templates

Templates are text files that are used to format the data gathered from the form. Each control in the form has a unique name, and in the template, these names are used as variables. For example, if a form had a input area named age, then a variable would be defined named ~age~. Anywhere you wrote ~age~ on the template, it would be replaced with whatever value the user entered in the age input area.

In addition to variables defined by the controls you put on the form, Saveform defines the following additional variables (all must be enclosed in the ~'s):

The following variables may or may not be set, depending on the browser:
  • http_from -- this is the email address of the user
  • http_user_agent -- the browser name
  • referrer_url -- the url that brought them here
  • remote_host -- the user's internet address (if none, this is set to their IP address instead)
  • remote_addr -- the user's IP address A template can contain conditionals at the beginning of any line. The conditionals must evaluate to true, or the line is not displayed.


    In some cases, you may want to display different things depending on the data entered. For example, you may refer to the user by name if they entered their name, and use a generic response if not. Or, if a check box was checked, you may want to print out a different message than if it was not checked.

    To enable this, you can use Conditionals, statements that must be true, or the text after them is not processed. Conditionals can be used in both templates and runfiles.

    DON'T PANIC! If this makes no sense to you, just ignore it. You don't need conditionals to use Saveform, they're just an extra.

    A conditional is any line that contains "| " in it. Everything before the "| " is the conditional, everything after is the line that is processed if the conditional is true.

    Some examples -- in a template:

    '~name~'| text            <-- print text if name was filled in
    !'~name~'| text           <-- print text if name was not filled in
    '~name~' eq 'joey'| text  <-- print text if name = 'joey'
    !'~name~' eq 'joey'| text <-- print text if name is not equal to 'joey'
    More examples -- in a runfile:

    '~name~'| command            <-- run command if name was filled in
    !'~name~'| command           <-- run command if name was not filled in
    '~name~' eq 'joey'| command  <-- run command if name = 'joey'
    !'~name~' eq 'joey'| command <-- run command if name is not equal to 'joey'
    Here is an example of using several conditionals on one line.
    ('~name~') and ('~age~') and (!'~name~ eq 'joey')| You entered your name and age, and your name is not joey.

    (Here's the catch: to use conditionals, you really should know how to program in perl. I skimped, and made perl handle conditionals directly. This means that they can be very powerful and complicated, but you have to already know perl to harness that power. Here, I just describe simple conditionals. If you are already a perl programmer, note that a "conditional" is just evaluated by perl, and if it evaluates to anything other than '', it is true. Think of conditionals as the first part of an 'if' statement.)



    Saveform is Copyright (C) 1995 by Joey Hess <>

    This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.

    This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.