tcl-doc.xml
Delivered as text/xml
[ hide source ] | [ make this the default ]
File Contents
<?xml version='1.0' ?> <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [ <!ENTITY % myvars SYSTEM "../variables.ent"> %myvars; ]> <sect1 id="tcl-doc" xreflabel="Documenting Tcl Files: Page Contracts and Libraries"> <title>Documenting Tcl Files: Page Contracts and Libraries</title> <authorblurb> <para>By <ulink url="mailto:jsalz@mit.edu">Jon Salz</ulink> on 3 July 2000 </para> </authorblurb> <itemizedlist> <listitem><para>Tcl procedures: /packages/acs-kernel/tcl-documentation-procs.tcl</para></listitem> </itemizedlist> <sect2 id="tcl-doc-bigpicture"> <title>The Big Picture</title> <para>In versions of the OpenACS prior to 3.4, <ulink url="/doc/standards">the standard place</ulink> to document Tcl files (both Tcl pages and Tcl library files) was in a comment at the top of the file:</para> <programlisting> # # <emphasis>path from server home</emphasis>/<emphasis>filename</emphasis> # # <emphasis>Brief description of the file's purpose</emphasis> # # <emphasis>author's email address</emphasis>, <emphasis>file creation date</emphasis> # # <ulink url="http://www.loria.fr/~molli/cvs/doc/cvs_12.html#SEC93">$Id: tcl-doc.xml,v 1.7.16.1 2023/07/10 08:36:09 gustafn Exp $</ulink> # </programlisting> <para> In addition, the inputs expected by a Tcl page (i.e., form variables) would be enumerated in a call to <computeroutput>ad_page_variables</computeroutput>, in effect, documenting the page's argument list. </para> <para>The problem with these practices is that the documentation is only accessible by reading the source file itself. For this reason, ACS 3.4 introduces a new API for documenting Tcl files and, on top of that, a web-based user interface for browsing the documentation:</para> <itemizedlist> <listitem><para><emphasis role="strong"><computeroutput><link linkend="tcl-doc-ad-page-contract">ad_page_contract</link></computeroutput></emphasis>: Every Tcl page has a <emphasis role="strong">contract</emphasis> that explicitly defines what inputs the page expects (with more precision than <computeroutput>ad_page_variables</computeroutput>) and incorporates metadata about the page (what used to live in the top-of-page comment). Like <computeroutput>ad_page_variables</computeroutput>, <computeroutput>ad_page_contract</computeroutput> also sets the specified variables in the context of the Tcl page.</para></listitem> <listitem><para><emphasis role="strong"><computeroutput><link linkend="tcl-doc-ad-library">ad_library</link></computeroutput></emphasis>: To be called at the top of every library file (i.e., all files in the <computeroutput>/tcl/</computeroutput> directory under the server root and <computeroutput>*-procs.tcl</computeroutput> files under <computeroutput>/packages/</computeroutput>).</para></listitem> </itemizedlist> <para> This has the following benefits: </para> <itemizedlist> <listitem><para>Facilitates automatic generation of human-readable documentation.</para></listitem> <listitem><para>Promotes security, by introducing a standard and automated way to check inputs to scripts for correctness.</para></listitem> <listitem><para>Allows graphical designers to determine easily how to customize sites' UIs, e.g., what properties are available in templates.</para></listitem> <listitem><para>Allows the request processor to be intelligent: a script can specify in its contract which type of abstract document it returns, and the request processor can transform it automatically into something useful to a particular user agent. (Don't worry about this for now - it's not complete for ACS 3.4.)</para></listitem> </itemizedlist> </sect2> <sect2 id="tcl-doc-ad-page-contract" xreflabel="ad_page_contract"> <title>ad_page_contract</title> <para> Currently <computeroutput>ad_page_contract</computeroutput> serves mostly as a replacement for <computeroutput>ad_page_variables</computeroutput>. Eventually, it will be integrated closely with the documents API so that each script's contract will document precisely the set of properties available to graphical designers in templates. (Document API integration is subject to change, so we don't describe it here yet; for now, you can just consider <computeroutput>ad_page_contract</computeroutput> a newer, better, documented <computeroutput>ad_page_variables</computeroutput>.) </para> <para>Let's look at an example usage of <computeroutput>ad_page_contract</computeroutput>:</para> <programlisting> # /packages/acs-kernel/api-doc/www/package-view.tcl ad_page_contract { version_id:integer public_p:optional kind { format "html" } } { Shows 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 view the type of API to view. One of <code>procs_files</code>, <code>procs</code>, <code>content</code>, <code>types</code>, or <code>gd</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$ } </programlisting> <para> Note that: </para> <itemizedlist> <listitem><para><emphasis role="strong">By convention, <computeroutput>ad_page_contract</computeroutput> should be preceded by a comment line containing the file's path</emphasis>. The comment is on line 1, and the contract starts on line 2. </para></listitem> <listitem><para><emphasis role="strong"><computeroutput>ad_page_contract</computeroutput></emphasis>'s first argument is the list of expected arguments from the HTTP query (<computeroutput>version_id</computeroutput>, <computeroutput>public_p</computeroutput>, <computeroutput>kind</computeroutput>, and <computeroutput>format</computeroutput>). Like <computeroutput>ad_page_variables</computeroutput>, <computeroutput>ad_page_contract</computeroutput> sets the corresponding Tcl variables when the page is executed. </para></listitem> <listitem><para><emphasis role="strong">Arguments can have defaults</emphasis>, specified using the same syntax as in the Tcl <computeroutput>proc</computeroutput> (a two-element list where the first element is the parameter name and the second argument is the default value). </para></listitem> <listitem><para><emphasis role="strong">Arguments can have flags</emphasis>, specified by following the name of the query argument with a colon and one or more of the following strings (separated by commas): </para> <itemizedlist> <listitem><para><emphasis role="strong"><computeroutput>optional</computeroutput></emphasis>: the query argument doesn't need to be provided; if it's not, the variable for that argument simply won't be set. For instance, if I call the script above without a <computeroutput>public_p</computeroutput> in the query, then in the page body <computeroutput>[info exists public_p]</computeroutput> will return 0. </para></listitem> <listitem><para><emphasis role="strong"><computeroutput>integer</computeroutput></emphasis>: the argument must be an integer (<computeroutput>ad_page_contract</computeroutput> will fail and display and error if not). This flag, like the next, is intended to prevent clients from fudging query arguments to trick scripts into executing arbitrary SQL. </para></listitem> <listitem><para><emphasis role="strong"><computeroutput>sql_identifier</computeroutput></emphasis>: the argument must be a SQL identifier (i.e., <computeroutput>[string is wordchar $the_query_var]</computeroutput> must return true). </para></listitem> <listitem><para><emphasis role="strong"><computeroutput>trim</computeroutput></emphasis>: the argument will be [string trim]'ed. </para></listitem> <listitem><para><emphasis role="strong"><computeroutput>multiple</computeroutput></emphasis>: the argument may be specified arbitrarily many times in the query string, and the variable will be set to a list of all those values (or an empty list if it's unspecified). This is analogous to the <computeroutput>-multiple-list</computeroutput> flag to <computeroutput>ad_page_variables</computeroutput>, and is useful for handling form input generated by <computeroutput><SELECT MULTIPLE></computeroutput> tags and checkboxes. </para> <para>For instance, if <computeroutput>dest_user_id:multiple</computeroutput> is specified in the contract, and the query string is</para> <programlisting> ?dest_user_id=913&dest_user_id=891&dest_user_id=9 </programlisting> <para> then <computeroutput>$dest_user_id</computeroutput> is set to <computeroutput>[list 913 891 9]</computeroutput>. </para></listitem> <listitem><para><emphasis role="strong"><computeroutput>array</computeroutput></emphasis>: the argument may be specified arbitrarily many times in the query string, with parameter names with suffixes like <computeroutput>_1</computeroutput>, <computeroutput>_2</computeroutput>, <computeroutput>_3</computeroutput>, etc. The variable is set to a list of all those values (or an empty list if none are specified). </para> <para>For instance, if <computeroutput>dest_user_id:array</computeroutput> is specified in the contract, and the query string is</para> <programlisting> ?dest_user_id_0=913&dest_user_id_1=891&dest_user_id_2=9 </programlisting> <para> then <computeroutput>$dest_user_id</computeroutput> is set to <computeroutput>[list 913 891 9]</computeroutput>.</para></listitem> </itemizedlist> </listitem> <listitem><para><emphasis role="strong">You can provide structured, HTML-formatted documentation for your contract</emphasis>. Note that format is derived heavily from Javadoc: a general description of the script's functionality, followed optionally by a series of named attributes tagged by at symbols (<computeroutput>@</computeroutput>). You are encouraged to provide: </para> <itemizedlist> <listitem><para>A description of the functionality of the page. If the description contains more than one sentence, the first sentence should be a brief summary. </para></listitem> <listitem><para>A <emphasis role="strong"><computeroutput>@param</computeroutput></emphasis> tag for each allowable query argument. The format is </para> <programlisting> @param <emphasis>parameter-name</emphasis> <emphasis>description...</emphasis> </programlisting> </listitem> <listitem><para>An <emphasis role="strong"><computeroutput>@author</computeroutput></emphasis> tag for each author. Specify the author's name, followed his or her email address in parentheses.</para></listitem> <listitem><para>A <emphasis role="strong"><computeroutput>@creation-date</computeroutput></emphasis> tag indicating when the script was first created.</para></listitem> <listitem><para>A <emphasis role="strong"><computeroutput>@cvs-id</computeroutput></emphasis> tag containing the page's CVS identification string. Just use <computeroutput>$Id: tcl-documentation.html,v 1.2 2000/09/19 07:22:35 ron Exp $</computeroutput> when creating the file, and CVS will substitute an appropriate string when you check the file in.</para></listitem> </itemizedlist> <para> These <computeroutput>@</computeroutput> tags are optional, but highly recommended!</para></listitem> </itemizedlist> </sect2> <sect2 id="tcl-doc-ad-library" xreflabel="ad_library"> <title>ad_library</title> <para> <computeroutput>ad_library</computeroutput> provides a replacement for the informal documentation (described above) found at the beginning of every Tcl page. Instead of: </para> <programlisting> # /packages/acs-kernel/00-proc-procs.tcl # # Routines for defining procedures and libraries of procedures (-procs.tcl files). # # jsalz@mit.edu, 7 Jun 2000 # # $Id: tcl-doc.xml,v 1.7.16.1 2023/07/10 08:36:09 gustafn Exp $ </programlisting> <para> you'll now write: </para> <programlisting> # /packages/acs-kernel/00-proc-procs.tcl ad_library { Routines for defining procedures and libraries of procedures (<code>-procs.tcl</code> files). @creation-date 7 Jun 2000 @author Jon Salz (jsalz@mit.edu) @cvs-id $Id$ } </programlisting> <para> Note that format is derived heavily from Javadoc: a general description of the script's functionality, followed optionally by a series of named attributes tagged by at symbols (<computeroutput>@</computeroutput>). HTML formatting is allowed. You are encouraged to provide: </para> <itemizedlist> <listitem><para>An <emphasis role="strong"><computeroutput>@author</computeroutput></emphasis> tag for each author. Specify the author's name, followed his or her email address in parentheses.</para></listitem> <listitem><para>A <emphasis role="strong"><computeroutput>@creation-date</computeroutput></emphasis> tag indicating when the script was first created.</para></listitem> <listitem><para>A <emphasis role="strong"><computeroutput>@cvs-id</computeroutput></emphasis> tag containing the page's CVS identification string. Just use <computeroutput>$Id: tcl-documentation.html,v 1.2 2000/09/19 07:22:35 ron Exp $</computeroutput> when creating the file, and CVS will substitute an appropriate string when you check the file in.</para></listitem> </itemizedlist> <para><phrase role="cvstag">($Id: tcl-doc.xml,v 1.7.16.1 2023/07/10 08:36:09 gustafn Exp $)</phrase></para> </sect2> </sect1>