ACS Documentation : ACS Core Architecture Guide : API Publication : Publishing URLs
/user-search
page is the canonical example of a "URL
API", in that it behaves like a function: it accepts a defined set of
inputs; it returns a defined set of outputs; you "invoke" it
programmatically (by redirecting the browser to its URL).
Prior to ACS 3.3.1, the only documentation for a URL like
/user-search
would typically reside in comments at the top
of the corresponding file on the server. The inputs expected by a URL
would usually be enumerated in a call to
ad_page_variables
or, worse yet, in a comment somewhere
in the vicinity of a call to
set_the_usual_form_variables
.
ACS 3.3.1 supersedes this informal combination of page header comments
and ad_page_variables
with the new procedure
ad_page_contract
, which enables us to
present the definition and documentation of a URL API separately from
its implementation.
ad_page_contract
ad_page_contract
is:
ad_page_contract doc-string arg-list
ad_page_contract
should be called at the top of every
Tcl page, in place of a header comment and a call to
ad_page_variables
.
The arg-list
argument enumerates the variables
that the page expects to be included in the form data set. Like
ad_page_variables
, ad_page_contract
sets the
specified arguments as variables in the context of the Tcl page.
In addition to a name, each entry in the
arg-list
can have a default
value, specified using the same syntax as proc
:
a two-element list where the first element is the argument name and
the second argument is the default value.
ad_page_variables
(which only ensures that all
expected inputs are supplied), ad_page_contract
actually
validates page input values. Validation rules are specified by
following the argument name with a colon and then one or more of the
following flags (separated by commas if more than
one):
optional
: the argument doesn't need
to be provided; if it's not, the variable for that argument simply
won't be set in the context of the Tcl page.
integer
: the argument must be an
integer (ad_page_contract
will present an error message
to the user if not). This flag, like the next, is intended to prevent
clients from smuggling SQL
through page arguments.
naturalnum
:
Pluggable filter, installed by default, that makes sure the value is a natural number, i.e.
non-decimal numbers >= 0.
nohtml
:
Pluggable filter, installed by default, that disallows any and all html.
html
Pluggable filter, installed by default, that disallows any registered "naughty" HTML flags.
Naughty HTML tags are registered in the [ns/server/servername/acs/antispam]
section
of the ACS parameters file and processed with ad_check_for_naughty_html.
The purpose of screening naughty html is to prevent users from uploading
HTML with tags that hijack page formatting.
allhtml
:
Pluggable filter, installed by default, that allows any and all html. Use of this filter
is not recommended, except for cases when the HTML will not be presented to the user or there is some
other reason for overriding the site-wide control over naughty html.
tmpfile
:
Checks to see if the path and file specified by tmpfile are allowed on this system.
sql_identifier
: the argument must be
a SQL identifier (i.e., [string is wordchar
$the_query_var]
must return true).
trim
: the argument will be [string
trim]'ed.
multiple
: the argument may be
specified zero or more times in the form data set, and the variable
will be set to a list of all those values, or an empty list if none
are provided. This is analogous to the -multiple-list
flag to ad_page_variables
, and is useful for handling the
input generated by <select multiple>
and
<input type=checkbox>
tags.
For instance, if user_id:multiple
is specified in the
contract, and the query string is
then?user_id=1&user_id=2&user_id=3
$user_id
will be set to [list 1 2 3]
.
array
: the argument may be specified
zero or more times in the form data set, with variables names whose
suffixes follow this convention: _0
, _1
,
_2
, _3
, ... The variable is set to a list of
all those values, or an empty list if none are specified.
For instance, if user_id:array
is specified in the
contract, and the query string is
then the following variables will be set:?user_id.owner=3&user_id.maintainer=2&user_id.reviewer=1
set user_id(owner) 3 set user_id(maintainer) 2 set user_id(reviewer) 1
ad_proc
and ad_library
,
ad_page_contract
accepts Javadoc-inspired documentation
strings, i.e., a general description of the page's function, followed
optionally by a series of named attributes tagged with @
signs:
@param
tags, one for
each argument; the format is
@param parameter-name description...
@author
tags, one for
each author; specify the author's name, followed by his or her email
address in parentheses
@creation-date
tag, indicating
when the page was first created
@cvs-id
tag containing the
page's CVS identification string; just use $Id$
when creating the file, and CVS will substitute an appropriate string
when you check the file in.
@
tags are optional, but highly recommended. (For
ACS Core Team programmers, they are mandatory.)
ad_page_contract
:
# /www/recipes/one.tcl ad_page_contract { Presents one recipe, optionally in a printer-friendly format @param recipe_id the ID of the recipe to be presented @param printable_p printer-friendly or not? @author Michael Yoon (michael@ardigita.com) @creation-date 1 January 2001 @cvs-id $Id$ } { recipe_id:integer printable_p:integer }
Here's a more sophisticated example from the forthcoming API Browser:
By convention,# /packages/acs-core/api-doc/www/package-view.tcl ad_page_contract { Shows the APIs for a particular package. @param version_id the ID of the version whose API to view. @param public_p view only public APIs? @param kind the type of API to view. One of <code>procs_files</code>, <code>procs</code>, <code>content</code>, <code>types</code>, or <code>graphic-designer</code>. @param format the format for the documentation. One of <code>html</code> or <code>xml</code>. @author Jon Salz (jsalz@mit.edu) @creation-date 3 Jul 2000 @cvs-id $Id$ } { version_id:integer public_p:optional kind { format "html" } }
ad_page_contract
is preceded by a comment
line containing the file's path. The comment is on the first line of
the file, and the contract starts on the second.
ad_page_contract
with the next
iteration of the Document Builder API. It will then support explicit
specification of what type of content (e.g.,
html-content-pane
) the page returns, which the Request
Process can use for document transformation (e.g., master template
wrapping, WAP presentation) and template writers can use to determine
what document properties (i.e., variables) are available for each URL.