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
and
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 () @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 ofprocs_files
,procs
,content
,types
, orgraphic-designer
. @param format the format for the documentation. One ofhtml
orxml
. @author Jon Salz () @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.