It works like this. You have a SAS application you want to make accessible to users on the web. That application requires some input from the user, to select records or variables to be processed, or to set parameters for some computation.
You write an HTML form
in which the user can enter the
required information. When the user presses the SUBMIT button, the browser calls sascgi, passing the parameters defined in the form; sascgi
retrieves the parameters, runs SAS, and returns
the results to the user.
The script passes input parameters to the SAS program via the environment, which is much easier than trying to parse stdin in SAS. The SAS program is assumed to retrieve these parameters via %sysget(PARAM), or sysget('PARAM') in a data step. The SAS program can return results to the browser by one of three methods:
The SAS program can communicate success or failure (with an error message) by writing a message to a .err file or by returning a message starting with 'ERROR:' to STDOUT. [Not yet implemented]
<form> ... </form>
block in the document, referencing
this script as the ACTION attribute, as follows:
<form method="POST" action="http://your.server.name/cgi-bin/sascgi"> <input type="hidden" name="SASFILE" value="getlist.sas"> <input type="hidden" name="CONFIG" value="getlist.cfg"> <input type="hidden" name="TITLE" value="Page title"> <input type="hidden" name="OUTPUT_METHOD" value="STDOUT|LST|IMAGE"> <input type="hidden" name="REQUIRE" value="ITEMS LISTS"> ... other form elements ... </form>See the NCSA tutorial for information about fill-out forms. The
<input>
tags define names of parameters/arguments
which are passed to the SAS program (via setenv). Use type="hidden"
when you don't want the user to select or change the value; otherwise,
you can use any form element which generates a value.
Multi-valued arguments (e.g., scrolling lists using <SELECT MULTIPLE>
) are formatted
as a comma-separated string, surrounded by braces (or as specified
by the MULTIVALUE_FORMAT configuration parameter).
%sysget()
will give a harmless warning if
the SAS program references an unset (null) string.)
Note that the names of parameters passed from a form by the server
are case-sensitive (e.g., name='SASFILE' rather than
name='sasfile').
Use the upcase()
function in your
SAS program for string comparisons if you want to treat
the values of these query parameters
as case-insensitive.
Six form parameters have a special meaning to sascgi:
public_html
directory of user 'name'.
<PRE> ... </PRE>
or <TABLE> ... </TABLE>
.
<PRE> ...</PRE>
by sascgi, formfeeds are
translated to a horizontal rule (<HR>
), and the result is sent to the browser.
<img src="$sasfile.type">
.
The image type defaults to 'gif'. sascgi expects the SAS
program to produce an image file in the curent directory named
by the value of environment variable GSASFILE
. The
GSASFILE value will contain a filename and appropriate extension,
e.g., getlistNNNNNN.ps, where NNNNNN is a string of characters
to make the filename unique (in case of overlapping executions
of your program.)
<input type="text" name="ITEMS" value="10">
)
or to design the SAS program to provide a default.
%sysget()
macro function or the sysget()
datastep function.
OUTPUT_METHOD
specified in the form.
file STDOUT
, e.g.,
data _null_; file STDOUT; put <pre>; ... (output results) ... put <pre>;(If your output includes the '<' or '>' characters, this may cause problems for some browsers.) The
%htmltab
macro can also be used to produce output to STDOUT
containing either a preformatted printout or an HTML table from a SAS
dataset.
*-- Retrieve specified output file name; %let gsasfile =%sysget(GSASFILE); filename gsasfile "&gsasfile"; *-- Device options; goptions device=pscolor gaccess=sasgaedt gsfname=gsasfile gsflen=80 gsfmode=replace gprolog='2521'x;
filename
statements in the
config.sas
file which is used by sascgi.
For example, if your config.sas
contains
filename macros ('~web/sasuser/macros', '~web/sasuser/webmacros');an application could use
%include macros(htmltab);Alternatively, specify the full pathname to the file on the include statement.
setenv LISTS 1 setenv ITEMS 20 sas getlist
sascgi is also designed so that it can be run from the command line for debugging, e.g.,
setenv DEBUG 1 ./sascgi 'SASFILE=getlist.sas&LISTS=1&ITEMS=20'or, if you simply invoke sascgi with no parameters, it will prompt for name-value pairs until you type ^D:
./sascgi (offline mode: enter name=value pairs on standard input) LISTS=1 ITEMS=10 ^DThe parameters DEBUG, SASFILE, TITLE, and OUTPUT_METHOD may all be passed to this script via the form or the environment.
filename
statement.)
The HTML file contains a form to allow the user to enter the number of words/list and number of lists. The SASFILE and TITLE parameters are entered as hidden input elements, and so are not visible on the form.
<form method="POST" action="http://euclid.psych.yorku.ca/cgi/sascgi"> <input type="hidden" name="sasfile" value="getlist.sas"> <input type="hidden" name="title" value="Word List Generator"> <center> <table cellpadding=2> <tr> <td>Number of Items/list</td> <td><input type="text" name="ITEMS" size=4></td> </tr> <tr> <td>Number of Lists</td> <td><input type="text" name="LISTS" size=4 value="1"></td> </tr> </table> </center>Other elements within this form allow the user to select the minimum and maximum values of variables associated with each word, as well as the desired output format (HTML table, or preformatted text). In this application, each variable-selection field is accompanied by a small graphic image, and the fields are formatted as an HTML TABLE.
Enter minimum and/or maximum values to restrict the range of any variable. Leave these fields empty to use the entire range. <center> <table cellpadding=2> <tr> <th>Variable</th> <th>Range</th> <th>Minimum</th> <th>Maximum</th> <th>Distribution</th> </tr> <tr><td>Number of syllables</td> <td>1 - 5</td> <td><input type="text" name="SYL_MIN" size=5></td> <td><input type="text" name="SYL_MAX" size=5></td> <td><IMG WIDTH=224 HEIGHT=107 SRC="paivdens1.gif"></td> </tr> <tr><td>Number of letters</td> <td>3 - 14</td> <td><input type="text" name="LET_MIN" size=5></td> <td><input type="text" name="LET_MAX" size=5></td> <td><IMG WIDTH=224 HEIGHT=106 SRC="paivdens2.gif"></td> </tr> ...(more blocks like this) .... </table> <p> Output format: <select name="OUTPUT_FORMAT"> <option value="TABLE"> HTML table <option value="PRE"> HTML Text </select> <p> <input type="submit" value="Do it!"> <input type="reset" value="Clear & Retry"> <IMG WIDTH=159 HEIGHT=39 SRC="../../icons/NeXT.gif"alt="[NeXT]"> & <IMG WIDTH=32 HEIGHT=32 SRC="../../icons/SAShome.gif" alt="[SAS]"> </center> </form>Thus, in addition to the (hidden) SASFILE and TITLE parameters, the application-specific parameters passed to sascgi are named LISTS, ITEMS, SYL_MIN, SYL_MAX, LET_MIN, LET_MAX, ... and OUTPUT_FORMAT. The sascgi OUTPUT_METHOD parameter is not specified in the form, and so defaults to STDOUT.
getlist.sas
program.
This program retrieves the values of the parameters using the %sysget()
macro function:
%let items = %sysget(ITEMS); %let lists = %sysget(LISTS);The selection of items from the database is handled by a macro %select (not shown), which is invoked as follows
%select( out=sample, items=&items, lists=&lists, let_min=%sysget(LET_MIN), let_max=%sysget(LET_MAX), syl_min=%sysget(SYL_MIN), syl_max=%sysget(SYL_MAX), freq_min=%sysget(FREQ_MIN), freq_max=%sysget(FREQ_MAX), imag_min=%sysget(IMAG_MIN), imag_max=%sysget(IMAG_MAX), conc_min=%sysget(CONC_MIN), conc_max=%sysget(CONC_MAX), mean_min=%sysget(MEAN_MIN), mean_max=%sysget(MEAN_MAX), print=NO );Note that any parameters which are not specified in the input form are given null values. (The %select macro is designed so that the only required parameter is the number of items.) The items selected are placed in a dataset, SAMPLE. The dataset is printed to STDOUT as either an HTML TABLE or as PREformatted text using the %htmltab macro.
%macro outtab; %let outform = %sysget(OUTPUT_FORMAT); %if &outform = TABLE %then %let ver=3; %else %let ver=2; %htmltab(data=sample,out=STDOUT, id=Word, vars=freq imag conc meaning, by=list, caption=Word List, tabid=list, htmlver=&ver, ls=80, tmpfile=getlist); %mend; %outtab;
The form allows the user to choose the variable to be displayed (VAR)
from a pop-up <SELECT >
list,
and an optional value for the window-width (bandwidth) parameter
of the %density macro.
A pop-up list allows the selection of IMAGE/GIF or IMAGE/PS
for the OUTPUT_METHOD parameter.
<form method="POST" action="http://euclid.psych.yorku.ca/cgi/sascgi"> <input type="hidden" name="SASFILE" value="wwwdens.sas"> <input type="hidden" name="TITLE" value="Word List Distributions"> <table cellpadding=2> <tr> <td>Variable to display:</td> <td><select name="VAR"> <option value="FREQ">Word Frequency <option value="CONC">Concreteness Rating <option value="IMAG">Imagery Rating <option value="MEANING">Meaningfulness Rating <option value="LET">Number of Letters </select></td><br> </tr> <td>Window Width:</td> <td> <input type="text" name="WINDOW" size=6></td> </tr> <tr> <td>Output format:</td> <td><select name="OUTPUT_METHOD"> <option value="image/gif"> GIF image <option value="image/ps"> PostScript </select></td><br> </tr> </table> <p> <input type="submit" value="Do it!"> <input type="reset" value="Clear & Retry"> </form>
*-- Retrieve specified output file name for the graph; %let gsasfile =%SYSGET(GSASFILE); filename gsasfile "&gsasfile"; *-- Device options; goptions device=pscolor gaccess=sasgaedt gsfname=gsasfile gsflen=80 gsfmode=replace gprolog='2521'x; *-- Graph options; goptions vsize=4in hsize=7.5in htext=3 ftext=hwpsl009 hpos=120 vpos=100 lfactor=5; *-- Define the data library; libname pools '/Users/friendly/sasuser/pools/'; *-- Retrieve plot variable name; %let var = %sysget(VAR); %put Graphing variable = &var;The graph is produced using the %density and %boxaxis macros (from The SAS System for Statistical Graphics). The WINDOW parameter is passed directly to the %density macro (which provides a default computation if the value is null).
%include macros(boxanno); %include macros(density); axis1 label=(a=90 'Density') offset=(3,); pattern1 v=solid c=red; symbol1 v=none i=join c=black; %boxaxis(data=pools.paivio, out=boxanno, var=&var, pos=96, boxwidth=5); %density(data=pools.paivio, var=&var, out=densplot, window=%sysget(WINDOW), vaxis=axis1, haxis=axis2, symbol=symbol1, anno=boxanno, plotopt=%str(areas=1));
/usr/local/lib/perl5
.
OUTPUT_METHOD=IMAGE/GIF
.
I use the pstogif
script, obtained from the
latex2html package by Nikos Drakos (nikos@cbl.leeds.ac.uk),
which in turn uses ghostscript and the netpbm utilities.
If you are running SAS Version 6.11 or greater, sascgi can use
the IMGGIF
device driver directly to produce GIF images.
cd /usr/etc/httpd/htdocs mkdir tmp chmod +w tmp
You may want to add a line to your crontab.local to cleanup this directory periodically. I use:
10,30,50 * * * * root /usr/local/bin/find /usr/local/etc/httpd/htdocs/tmp/ -cmin +10 -exec rm -f {} \;which runs 3 times/hour to remove all files older than 10 minutes
#!/usr/local/bin/perlThis defines the path to the perl interpreter. Adjust this as necessary and make sure that it points to perl version 5.001 or higher.
rm
program on your system:
$SAS = '/usr/local/bin/sas'; # path to sas executable $RM = "/usr/local/bin/rm";
$httmp = '/usr/local/etc/httpd/htdocs/tmp'; # where SAS file get created $www_httmp = '/tmp'; #this path, relative to server rootYou will need to define permissions so that this directory is writeable by anyone.
$www_dir1 = '/users/faculty/friendly/sasuser/www'; $www_dir2 = '/users/faculty/friendly/sasuser/pools'; @sas_dirs = ( $www_dir1, www_dir2 );
Other configuration parameters are at the bottom of sascgi
following a line that reads __END__
.
They define default values for the output form, the
name and e-mail address of the application author,
and such things as the title of the output page
and other output formatting preferences.
Any of these values can be changed on the fly in the CONFIG file
but you will probably want to set some reasonable defaults here.
The most important of these is the OUTPUT_FORM, which defines a template into which the SAS output is substituted before being returned to the browser. The default value is:
OUTPUT_FORM= The following output was produced: <br> <center> @OUTPUT@ </center> View the saslog: @HREF_SASLOG@ .In the OUTPUT_FORM, '@OUTPUT@' stands for whatever output is produced by the SAS program; '@HREF_SASLOG@' is a link to the SAS log file produced when the program is run.
htmltab
macro
is useful for producing an HTML table
from a SAS dataset. It supports where
-clause observation selection, by
-variable processing, HTML Level 2
( <PRE> ... </PRE>
) or Level 3
(<TABLE> ... </TABLE>
) styles,
and output to a listing, a file, or STDOUT.