THE PARSE CGI OSAX
This OSAX will accelerate and simplify all your HTML form scripts.
Version 1.1
By Alex Powers and Mark Kriegsman
Copyright © 1995 Document Directions, Inc.
(617) 227-2100

Contents


Claim

The parse CGI OSAX will accelerate and simplify all your HTML form scripts. If you find that your scripts are faster and simpler with our OSAX, please send the $10 shareware fee.


Description

The parse CGI OSAX is used to decode, parse, and access the HTML form information that is passed in to an AppleScript CGI program by MacHTTP. It is meant to replace the use of the "DePlus," "Decode URL," and "Tokenize" OSAXen to handle incoming HTML forms and field data. In addition, it provides a streamlined interface that is specifically designed for CGI scripting.

New in version 1.1

We've received an extememly positive response from the users of our 1.0 OSAX, along with a number of requests for new features and functionalty. We've added support for the most frequently requested features:

The other OSAXen that our OSAX can replace (DePlus, Decode URL, and especially Tokenize) can sometimes be extremely useful for other processing inside CGI scripts. If you are using Tokenize for another part of your CGI script, remember to send the appropriate shareware fee to ACME Script Widgets.


Introduction | Description | Examples | Behavior | Who and why | Shareware | Contacting us

Examples

We've included more examples here, in addition to some general tips and techniques.

Example 1: Getting data from HTML forms into AppleScript variables

This is probably the most common operation found at the top of CGI scripts. The parse CGI OSAX has been explicitly designed to accelerate and simplify this process.
-- decode and parse all arguments
set formData to parse CGI arguments post_args

-- get specific fields
set first_name to CGI field "first_name" from formData
set last_name to CGI field "last_name" from formData
set processor to CGI field "processor" from formData default value "PowerPC"

Example 2: Updating Jon Wiederspan's "Level 5 Example"

The following code fragment is copied directly from Jon Wiederspan's "Level 5 Example Script". Jon's code returns a page showing all the incoming arguments. Below is the parsing code as it was published and as it can now be written using the parse CGI OSAX. The parse CGI command returns a list of records, where each record has a "field" and a "value" that describe a particular field from the HTML form. This makes it easy it loop through all the fields, which is what Jon's example does.
Jon Wiederspan's original code:
-- this creates a list of "name=value" pairs
set postarglist to tokenize post_args with delimiters {"&"}
		
-- The section below converts the list to readable output, putting each item onto a separate line.
-- Uses DecodeURL to convert %XX encodings and Tokenize/JoinList to
-- convert "+" to spaces.
		
-- store the original AppleScript text item delimiters
set oldDelim to AppleScript's text item delimiters
-- use "=" to delimit the pairs
set AppleScript's text item delimiters to {"="}
-- initialize postargtext in case the item is empty
set postargtext to ""
-- traverse the list item by item
repeat with currpostarg in postarglist
  set postargtext to postargtext & -|
  (Decode URL (dePlus (last text item of currpostarg))) & return & return
end repeat
-- restore the old AppleScript text item delimiters settings
set AppleScript's text item delimiters to oldDelim
Updated using the parse CGI OSAX
-- initialize postargtext		
set postargtext to ""

-- decode and parse all arguments
set formData to parse CGI arguments post_args

-- traverse the list of records
repeat with currField in formData
  set postargtext to postargtext & value of currField & return & return
end repeat

Example 3: Getting HTML "select multiple" fields into AppleScript lists

Most fields on HTML forms only need to return one value. Text, password, checkbox, radio, and hidden INPUT fields each only return one value each. Likewise, TEXTAREA fields return only one value, although it is often large.

Unlike those field types, a SELECT field can return a single value or multiple values, depending on its how it is set up. Here is an example of a SELECT field that supports multiple selections

Select as many toppings as you wish: 
<SELECT NAME="toppings" MULTIPLE>  <OPTION VALUE="nuts"           >Nuts
  <OPTION VALUE="cherries"       >Cherries
  <OPTION VALUE="sprinkles"      >Sprinkles (Jimmies)
  <OPTION VALUE="fudge" SELECTED >Hot Fudge
Here is how that field looks in a form. Use command-click to select items.
Select as many toppings as you wish:
Multiple values are sent to the CGI script as if they were separate fields with the same name. So,if the user selects "Nuts"and "Hot Fudge", the CGI script will be sent "toppings=nuts&toppings=fudge".

The parse CGI OSAX provides special support for this and (by default) returns the result as an AppleScript list. So, in the above example, the parse CGI command would return

{{field:"toppings", value:{"nuts","fudge"}}}
and CGI field "toppings" would return
{"nuts","fudge"}

There are three caveats when using "select multiple" fields, all of which can be easily dealt with if the CGI script and the HTML form are designed to work together.

  1. CGI scripts don't get sent information about the fields, just the data that the user entered. The CGI script cannot tell from what it gets passed whether a particular field was a "select multiple" field or not. The CGI can only tell whether or not there were multiple fields with the same name. (i.e., "toppings" appears twice in the list of fields). A form with two separate fields called "toppings" will return the same result as a form with one "select multiple" field. This basically means that the CGI scripter should be involved with the design of the HTML form.
  2. Always coerce "select multiple" fields to lists. Because of the previous situation, the parse CGI OSAX will only return an AppleScript list when the user selects more than one value from the "select multiple" field. If the user selects only "fudge", the parse CGI OSAX will return only "fudge" (a string), not {"fudge"} (a list with one string in it.) This also means that the CGI has to know a little about the form that is sending data, so that the script can coerce the return value to a list if the field was a "select multiple".
  3. Be aware any fields with the same name will also be combined. If the HTML form actually contains several fields with the same name, the parse CGI OSAX will combine them and return them as an AppleScript list. While this can be used for some interesting purposes, it is often the result of a typing error by the person creating the HTML form. Again, a little coordination between the form and the CGI script will prevent any problem.

    Sample script to handle "select multiple" field

    -- decode and parse all arguments
    set formData to parse CGI arguments post_args
    
    -- get the multiple-value field as a list
    -- if the user selects 2 or more things, everything is automatic
    -- if the user selects only one thing, a single value is returned, so
    --    we coerce the return value to a list
    -- if the user doesn't select any values, we want an empty list, so
    --    we ask for {} as the default value
    
    set toppings to (CGI field "toppings" from formData default value {}) as list
    
    -- toppings is now a list of values the user chose
    

    Keeping fields separate (suppressing the "combining into lists")

    You can suppress the list-combining behavior by specifying "combining duplicates false" or "without combining duplicates":
    set formData to parse CGI arguments post_args  without combining duplicates
    This will cause the parse CGI command to return each incoming field/value pair as a separate item, and will prevent it from creating lists from fields with the same name.

    Example 4: Using parse CGI to handle arguments other than POST

    Although the parse CGI OSAX will probably be most useful in handling GET or POST arguments from HTML forms, there are times when you need to pass arguments to a CGI script, but can't use an HTML form.

    For example, you may want to include arguments to a CGI in the HREF of a hyperlink. This would allow you to create an HTML page where certain hyperlinks automatically sent different sets of arguments to the same CGI. Here is an example of hyperlinks like these. Notice the use of "path arguments" (the part of the URL following the "$") to pass the arguments.

    Sort the users by <A HREF="sortusers.acgi$sortby=birthday">Birthday</a> 
                or by <A HREF="sortusers.acgi$sortby=IQ">IQ</a>
    Then in sortusers.acgi you can do this to find the correct field to sort by:
    -- find out what field to sort by
    set sortField to CGI field "sortby" from parse CGI arguments path_args
    -- sortField is now either "IQ" or "birthday"
    This allows you to easily send a number of named arguments to any CGI from inside a hyperlink. Thes same technique can be applied to the SEARCH arguments (the part of the URL following the "?").
    Introduction | Description | Examples | Behavior | Who and why | Shareware | Contacting us

    Exact behavior of the commands

    There are actually two commands in this package. The first, parse CGI arguments, does all the decoding and parsing and returns a list of records. The second command, CGI field, performs a high-speed lookup in the list of records.
    parse CGI arguments post_args
    parse CGI arguments post_args combining duplicates true_or_false
    parse CGI arguments post_args with combining duplicates
    parse CGI arguments post_args without combining duplicates
    This command does the hard part. It decodes the post arguments, including allowances for the use of "+" where "%20" would be more correct. It then creates a list of records from the POST arguments, where each record has a "field" and a "value" that are taken from the HTML form post data. So, input of "first_name=Alex%20C.&last_name=Powers" would produce:
    {{field:"first_name", value:"Alex C."}, 
     {field:"last_name", value:"Powers"}}

    By default, the parse CGI command also combines input fields with the same name into a single AppleScript list. This is provided to support use of "select multiple" fields. The input "topping=nuts&topping=fudge" would produce:

    {{field:"toppings", value: {"nuts","fudge"}}}
    If this behavior is suppressed by specifying "without combining duplicates", it would return
    {{field:"toppings", value:"nuts"}, 
     {field:"toppings", value:"fudge"}}
    CGI field field_name from form_data
    CGI field field_name from form_data default value default_value
    This command performs high-speed lookups in the list of records returned by parse CGI arguments. The input is the field name to search for. If the requested field is not found, or if the field's value is empty, then an optional default value can be returned. If no default is specified, and the search fails, the empty string is returned.

    The search for the field name is case sensitive, because HTML forms can have distinct fields whose names differ only in capitalization.


    Introduction | Description | Examples | Behavior | Who and why | Shareware | Contacting us

    Who we are and why we did this

    Document Directions, Inc. is a consulting and integration company specializing in electronic document management for financial services companies. We were preparing a demonstration system based on MacHTTP, and needed to boost the performance of the system. We examined our (relatively simple) CGI scripts, and noticed how much time and code went into parsing the CGI arguments. The parse CGI OSAX is the direct result of our optimization efforts. The added benefit was that we now have a very direct programming interface for CGI scripts.

    We have experience with Unix, Windows (NT and plain), and Macintosh platforms, building streamlined applications that provide powerful results. The parse CGI OSAX, we believe, is another good example of the leverage we provide to our clients, and now to the community at large.


    Introduction | Description | Examples | Behavior | Who and why | Shareware | Contacting us

    Shareware details

    We feel that the parse CGI OSAX will accelerate and simplify all your CGI scripts. If you find that your scripts are faster and simpler with our OSAX, please send the shareware fee listed below: Please send money orders or checks drawn on US Banks.
    Make payable to
    Document Directions, Inc.
    Send to
    Mark Kriegsman
    Document Directions, Inc.
    131 State Street
    Boston, MA 02109
    USA

    Introduction | Description | Examples | Behavior | Who and why | Shareware | Contacting us

    Contacting us

    Although we provide full support for our consulting clients, we cannot provide telelphone support for this OSAX. If you have comments, questions, or feedback about the parse CGI OSAX, please send e-mail to Kriegsman@aol.com or ddi@document.com.

    You can contact Mark Kriegsman in our Boston office at (617) 227-2100 to discuss consulting or development work.


    Introduction | Description | Examples | Behavior | Who and why | Shareware | Contacting us
    This package may be freely distributed in its unmodified state as long as this documentation is included.
    Neither Document Directions, Inc., nor the authors make any claim as the suitability of this program or information for any particular task. You examine and use this program and information at your own risk.
    Last updated 6/4/95