form-submit -- web form submission processing

Overview

form-submit is a CGI program at MV that provides a general-purpose interface for accepting data entered through an HTML form. In order to use it, you must have a page on the MV server, and you must create a control file that tells form-submit what to do. Depending on what the details of what you want done, you may also need one or more other files (for example, you are likely to want to define a confirmation page that is returned to the user after the form has been processed).

Any file that is used by form-submit can have certain encodings in it that allows, among other things, insertion of data from the form being processed. Remember that each field in a form has a tag (aka a name) and, hopefully, a value. In a file used by form-submit, a sequence consisting of a tilde (~) followed immediately by the name of a tag will be replaced by the value of that tag. Let's say your form includes a fill-in field such as:

   <input name="name" TYPE="text" SIZE=40 MAXLENGTH=40>

Then a file processed by form-submit could include the sequence:

   Name:  ~name

(e.g., as part of a mail message that is sent to you whenever the form is processed). Instead of "~name" in the mail message, you would receive the actual name that was entered into this field.

The form-submit control file

To use form-submit, give your form a name and create a file with that name and the extension ".submit". You might, for example, create a test form and create a file "test.submit". (If you're using a system that does not permit long filenames or long suffixes, you can give the file a long name as you upload it.) Your HTML form should invoke form-submit with a sequence like this:

   <form
      action="/cgi-bin/form-submit/path/formname"
      method="post">
   [fields and stuff]
   </form>

with "path" being the full path to the directory containing your form relative to the top of the web server, and "formname" being the name of the form. (NB: you can also use method="get" -- form-submit will handle either the "get" or "post" method.) If you are J. Random User and your home page has a URL of

	http://www.mv.com/ipusers/jruser

you might create a subdirectory "forms" and the form sequence to invoke your "test" form might read:

   <form
      action="/cgi-bin/form-submit/ipusers/jruser/forms/test"
      method="get">
   [fields and stuff]
   </form>

It is also permissible to provide some extra information after the path by preceding that information with a colon. e.g.:

      action="/cgi-bin/form-submit/ipusers/jruser/forms/test:form1"

This information (e.g. "form1" in the above) is available through the "path-tag" lines in the .submit file. This can be used as an alternate way to supply a hidden piece of data.

Details of the .submit file are given below, but we'll start out with a short example first. A test.submit file such as this:

	# form-submit control file for "test"
	
	Tag-Required:	name
	Tag-Required:	addr-1

	Email-to:	myself@jruser.mv.com
	Email-from:	form-test@www.mv.net
	Email-file:	test.msg

	Return-document:	test-done.html

says that the tags "name" and "addr-1" must be supplied by the submitter (otherwise an error will be indicated); that the results of the form should be emailed to "myself@jruser.mv.com"; that the file that contains the template email message is named "test.msg"; and that a document named "test-done.html" should be presented to the submitter after the form has been accepted.

Following are the kinds of lines that make up the .submit file. Note that any files mentioned in the .submit file must be in the same directory as that file, and remember that they can contain embedded sequences to provide the data submitted through the form.

#
A line beginning with a pound sign and a space is ignored, so it can be used as a comment. Blank lines are also ignored.

Email-File filename
If the results of this form are being emailed (i.e. if there is an "email-to" line), this specifies the name of a file to be used as the body of the email message. The email-file should begin with whatever header elements you want to supply (particularly a Subject: line), a blank line, and the body of the message. If you don't supply an email file, form-submit will make something up, but don't count on its format to remain the same over time.

Email-From email-address
If the results of this form are being emailed, this specifies the "from" address in the email message.

Email-To email-address
This specifies that the results of the form should be sent by email, and also provides the destination address (i.e., who gets the mail). For multiple recipients, provide a space-separated list in quotes, for example:
Email-To: "fred@some_domain barney@another_domain"

Log-From filename
If the results of this form are being logged into a file (i.e. if there is a "log-into" line), this specifies the name of a file to be used as the template for the log file. This template will be appended to any existing file, with the appropriate substitutions made. If you don't supply a log-from file, form-submit will log the form data all on one line. Each line starts with the date and time, and is followed by a list of all of the tag names and their values, each separated by a tab.

Log-Into filename [Public|Private|Mode nnn]
Specifies that the results of the form should be put into the named file. Note that it's permissible to have the results emailed and logged, both. If you log your forms into a file, please remember to keep track of its disk usage.

The filename may be optionally followed by one of the following, which affect the way that the file is created if it does not already exist:

If you omit the creation mode, the default is Private.

Path-Required Specifies that a "path-tag" item is required.

Path-Tag variable-name
If any data is given after the path in the form submission line (after a colon, as described above), this data is put into the environment variable named here. You shouldn't really be concerned with this, it's a piece of old functionality.

Return-Document filename
Provides the name of an HTML document to return to the submitter after the form has been processed. This should be some kind of confirmation page. If this is omitted, form-submit will make something up.

Tag name value
Pretends that a tag "name" was included with the form, with a value "value." The value can be enclosed in quotes to include spaces and other punctuation; note that if you want a blank value, just use two double-quotes. Tag can also be used to change the value of a particular tag; you can use this statement to maintain variables.

Tag-Default name value
Same as "Tag," but only has effect if the tag "name" was not supplied in the form submission.

Tag-Required name
Specifies that tag "name" must be present in the submitted form.


More about substitutions

It was mentioned above that, in any file processed by form-submit, a sequence of "~tagname" would be replaced by the data entered into the field with a tag of "tagname." Here's more information about tilde-substitutions.

One thing to note is that if any substitution fails, in general the original text comes through. For example, if you use ~name and there was no data associated with a tag "name," the string "~name" will come through instead. Use of "Tag-Default" lines in the .submit file can prevent this.

~~
If you need to include a tilde in text (in a file that's being processed by form-submit), use two tildes in a row.

~tagname
Is replaced by the value of the form tag "tagname."

~$variable
This is replaced by the value of an environment variable "variable." This is a UNIX environment variable; you might be interested in some web server variables such as REMOTE_HOST (the hostname of the submitter).

The special variable DATE (i.e., ~$DATE) can be used to return the current local date as mm/yy/dd hh:mm:ss. This variable may be followed by a plus sign and a strftime-format style format string in quotes to produce a tailored date string (make sure to include the quotes, not doing so may yield unexpected results). For example,
~$DATE+"%A %B %e, %Y"
might produce Thursday September 5, 1996.

~:tagname
If there is no tag "tagname" or its value is blank, this is replaced by the string "no" . Otherwise (there is a value associated with "tagname"), this is replaced by the string "yes". Among other things, this can be used in simple conditional tests (see below). But in one radical example of the use of substitutions, this could be used to select different files depending on the presence of a tag in the submitted form. Remembering that even the .submit file is subject to these substitutions, you might have a line:

	Log-From:	test.template-name-~:name

which would result in selecting either the file "test.template-name-yes" or "test.template-name-no" depending on whether the tag "name" was present in the input.

~+filename
Inserts the contents of "filename" at this point.


Conditional output

form-submit supports some simple testing and conditional processing to help deal with variances in the input given to it. Complex tasks are beyond the range of this utility; however these testing and conditional functions add some flexibility to basic forms processing.

As with substitutions, all constructs processed by form-submit are indicated by a tilde character. The elements used in testing and conditional output follow. It may help to view the guest book example while reviewing this list.

~? term1 relation term2 body
This compares the two terms via the given relation, and emits the body if the relationship is true. (The body is delimited by the various other elements described in this section.) Either term can be a quoted string, a variable substitution as described above, or a single word. For example:

      ~?~:name == yes

will test to see if the submitter has entered data into a form field with a tag of "name".

Relations that can be used:

There are also case-insensitive versions of the above relational tests: the case-insensitive variation is formed by preceding a '@' character to the relation. For example, "@?==" does a case-insensitive wildcard match.

There are also notted versions of all of the above combinations. The "not" variation is formed by preceding the relation with a '!' character, and removing one of the two adjacent '=' characters. Thus, '!@.=' means "case-insensitive regular expression non-match".

Note: for backward compatibility, "@!=" is provided as an equivalent to "!@="

 

~{
Begins a body of text that is affected by a conditional test. (A test must be immediately followed by this.) This, and the corresponding body closing, is used to identify the part of the text that is affected by a test.

~}
Ends a body of text and the conditional processing applied to it.

~}{
Ends a body of text, and opens a new body of text with the sense of the conditional test reversed. i.e., this functions as an else clause.

-
The minus sign when used immediately after one of the text body delimiting marks (~{, ~}, and ~}{) acts as a line continuation character, -- any newline immediately following will be supressed if it would otherwise be emitted.

Suppose (as in the guestbook example) you have an input form in which a submitter can enter their name and optionally a personal URL. You might want the name to be enclosed in an HTML markup that would reference that URL if given, and not have that markup if the URL is omitted. Assuming tags "name" and "url", the following can be used to that effect:

      ~?~:url==yes ~{-
      Name: <a href=~url>~name</a><br> ~}{-
      Name: ~name<br> ~}

Here, if there is a URL given, the line with the link reference is emitted, otherwise the one with just the name is used. Note the use of the "-" continuation characters to suppress redundant newlines from being emitted.


Omitted Data

Sometimes you'll find that the browser doesn't send information for one or more fields in your form. For instance, if you have radio buttons or checkboxes, but none of them have been selected, most browsers won't send anything. form-submit has no way of knowing about fields that aren't sent by the client, so when you try to substitute for one of these fields, e.g. ~radio-field, no substitution will be possible and you'll get the template ("~radio-field") returned. One way to guard against this is to use Tag-Default for any field that might not be supplied by the browser. For example:

Tag-Default radio-field ""

This says that if the field radio-field isn't supplied by the browser, it should be set to "" (a blank string).


Examples

Here are a couple of examples to help with the use of form-submit.

Results by email
An example of a simple form that uses form-submit to report its results via email.

guest book
Maintains a guest book of people who have submitted their information; users can add their information and view the previous submissions.

The End

form-submit was written at MV Communications, Inc. mostly in 1994 but modified slightly for personal home pages in 1996. It is likely to evolve. Your comments on its functionality, its future, and this document are welcome.