Commit 01a59427 authored by Frank Bergmann's avatar Frank Bergmann

- OpenACS 5.9 Import

parent e6b7adeb
<?xml version="1.0"?>
<queryset>
<fullquery name="template::paginator::init.count_query">
<querytext>
select count(*) from ($original_query) t
</querytext>
</fullquery>
</queryset>
set package_id [apm_package_id_from_key "acs-templating"]
set size [parameter::get -package_id $package_id -parameter TemplateCacheSize -default 200000]
ns_cache create template_cache -size $size
set size [parameter::get -package_id $package_id -parameter TemplateQueryCacheSize -default 20000]
ns_cache create template_query_cache -size $size
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace cm_widget</h2><blockquote>Procedures associated with custom metadata widgets for
basic CR content types</blockquote><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>The namespace cm_widget currently contains no public
methods.</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><p>
<b>Private Methods</b>:<br>
</p><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="cm_widget::validate_description" id="cm_widget::validate_description"><font size="+1" weight="bold">cm_widget::validate_description</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Make sure that description &lt;= 4000
bytes</blockquote><dl><dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>value</code><font color="red">*</font>
</td><td align="left">The submitted value of the description form
element</td>
</tr></table>
</dd></dl>
</td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace cms_rel</h2><blockquote>Procedures for managing relation items and child
items</blockquote><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>
<a href="#cms_rel::sort_child_item_order">cms_rel::sort_child_item_order</a><br><a href="#cms_rel::sort_related_item_order">cms_rel::sort_related_item_order</a><br>
</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><b>Public Methods:</b><br><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="cms_rel::sort_child_item_order" id="cms_rel::sort_child_item_order"><font size="+1" weight="bold">cms_rel::sort_child_item_order</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Resort the child items order for a given content item,
ensuring that order_n is unique for an item_id. Chooses new order
based on the old order_n and then rel_id (the order the item was
related)</blockquote><dl><dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>item_id</code><font color="red">*</font>
</td><td align="left">The item for which to resort child items</td>
</tr></table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="cms_rel::sort_related_item_order" id="cms_rel::sort_related_item_order"><font size="+1" weight="bold">cms_rel::sort_related_item_order</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Resort the related items order for a given content
item, ensuring that order_n is unique for an item_id. Chooses new
order based on the old order_n and then rel_id (the order the item
was related)</blockquote><dl><dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>item_id</code><font color="red">*</font>
</td><td align="left">The item for which to resort related items</td>
</tr></table>
</dd></dl>
</td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
This diff is collapsed.
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace content_add</h2><blockquote>Procedures regarding content methods</blockquote><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>
<a href="#content_add::content_method_html">content_add::content_method_html</a><br>
</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><b>Public Methods:</b><br><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="content_add::content_method_html" id="content_add::content_method_html"><font size="+1" weight="bold">content_add::content_method_html</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Generates HTML stub for revision content method choices
for a content item</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>db</code><font color="red">*</font>
</td><td align="left">A database handle</td>
</tr><tr>
<td align="right">
<code>content_type</code><font color="red">*</font>
</td><td align="left">The content type of the item</td>
</tr><tr>
<td align="right">
<code>item_id</code><font color="red">*</font>
</td><td align="left">The item id</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace content_method</h2><blockquote>Procedures regarding content methods</blockquote><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>
<a href="#content_method::flush_content_methods_cache">content_method::flush_content_methods_cache</a><br><a href="#content_method::get_content_methods">content_method::get_content_methods</a><br>
</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><b>Public Methods:</b><br><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="content_method::flush_content_methods_cache" id="content_method::flush_content_methods_cache"><font size="+1" weight="bold">content_method::flush_content_methods_cache</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Flushes the cache for content_method_types for a given
content type. If no content type is specified, the entire
content_method_types cache is flushed</blockquote><dl><dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>content_type</code><font color="red">*</font>
</td><td align="left">The content type, default null</td>
</tr></table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="content_method::get_content_methods" id="content_method::get_content_methods"><font size="+1" weight="bold">content_method::get_content_methods</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Returns a list of content_methods that are associated
with a content type, first checking for a default method, then for
registered content methods, and then for all content
methods</blockquote><dl>
<dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>content_type</code><font color="red">*</font>
</td><td align="left">The content type</td>
</tr></table>
</dd><dt><b>Returns:</b></dt><dd>A list of content methods or a list of label-value pairs of
content methods if the " -get_labels" option is specified</dd><dt><b>Options:</b></dt><dd><table><tr>
<td align="right"><code>get_labels</code></td><td align="left">Instead of a list of content methods, return a
list of label-value pairs of associated content methods.</td>
</tr></table></dd><dt><b>See Also:</b></dt><dd>content_method::get_content_method_options,
content_method::text_entry_filter_sql - <a href=""></a><br>
</dd>
</dl>
</td></tr>
</table><p>
<b>Private Methods</b>:<br>
</p><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="content_method::get_content_method_options" id="content_method::get_content_method_options"><font size="+1" weight="bold">content_method::get_content_method_options</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Returns a list of label, content_method pairs that are
associated with a content type, first checking for a default
method, then for registered content methods, and then for all
content methods</blockquote><dl>
<dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>content_type</code><font color="red">*</font>
</td><td align="left">The content type</td>
</tr></table>
</dd><dt><b>Returns:</b></dt><dd>A list of label, value pairs of content methods</dd><dt><b>See Also:</b></dt><dd>content_method::get_content_methods,
content_method::text_entry_filter_sql - <a href=""></a><br>
</dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="content_method::text_entry_filter_sql" id="content_method::text_entry_filter_sql"><font size="+1" weight="bold">content_method::text_entry_filter_sql</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Generate a SQL stub that filters out the text_entry
content method</blockquote><dl>
<dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>content_type</code><font color="red">*</font>
</td><td align="left"></td>
</tr></table>
</dd><dt><b>Returns:</b></dt><dd>SQL stub that possibly filters out the text_entry content
method</dd>
</dl>
</td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace doc</h2><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>The namespace doc currently contains no public
methods.</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><p>
<b>Private Methods</b>:<br>
</p><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name=""></a><br><small><i>  by simon</i></small>
</td></tr><tr><td>
<blockquote>called by parse_file, this procedure is given the body
of text between two namespace markers in a tcl library file and
parses out procedure source and comments</blockquote><dl><dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>text_lines</code><font color="red">*</font>
</td><td align="left">namespace text body</td>
</tr></table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td><blockquote>Parse API documentation from a Tcl page API
documentation is parsed as follows: Document is scanned until a
\@namespace directive is encountered. The remainder of the file is
scanned for \@private or \@public directives. When one of these
directives is encountered, the file is scanned up to a proc
declaration and the text in between is parsed as documentation for
a single procedure. The text between the initial \@private or
\@public directive and the next directive is considered a general
comment on the procedure Valid directives in a procedure doc
include: - \@author - \@param (for hard parameters) - \@see (should
have the form namespace::procedure. A reference to an entire
namespace should be namespace::. By convention the API for each
namespace should be in a file of the same name, so that a link can
be generated automatically). - \@option (for switches such as -foo)
- \@return</blockquote></td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>called by parse_comment_text</blockquote><dl><dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>comment_text</code><font color="red">*</font>
</td><td align="left">this should include the source text</td>
</tr></table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>called by parse_namespace</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>comment_text</code><font color="red">*</font>
</td><td align="left">body of comment text to be parsed through</td>
</tr><tr>
<td align="right">
<code>source_text</code><font color="red">*</font>
</td><td align="left">source text of the procedure</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>takes the absolute path of the tcl library directory
and parses through it</blockquote><dl>
<dt><b>Returns:</b></dt><dd>a long lists of lists of lists, each list element contains a
three-element list of the format { {info} {public procedures
listing } {private procedures listing} }</dd><dt><b>See Also:</b></dt><dd>namespace - <a href="util">util</a><br>
</dd><dd>proc - <a href="doc">doc::parse_file</a><br><a href="util">template::util::comment_text_normalize</a><br>
</dd>
</dl>
</td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace doc::util</h2><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>The namespace doc::util currently contains no public
methods.</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><p>
<b>Private Methods</b>:<br>
</p><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=" set split_name $see_name doc::util::text_divider split_name :: set name_length [llength $split_name] set see_namespace [join [lrange $split_name 0 [expr $name_length - 2]] \" set="" url=""><font size="+1" weight="bold">set split_name
$see_name doc::util::text_divider split_name :: set name_length
[llength $split_name] set see_namespace [join [lrange $split_name 0
[expr $name_length - 2]] \"\"] set url \"[doc::util::dbl_colon_fix
$see_namespace].html#[set see_name]\"</font></a></td></tr><tr><td><blockquote>procedure to deal with \@see comments</blockquote></td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>divides a string variable into a list of strings, all
but the first element beginning with the indicated text {marker;}
the first element of the created list contains all of the string
preceding the first occurrence of the text marker</blockquote><dl>
<dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>text</code><font color="red">*</font>
</td><td align="left">name of string variable (not the string value
itself)</td>
</tr><tr>
<td align="right">
<code>marker</code><font color="red">*</font>
</td><td align="left">the string indicating text division</td>
</tr>
</table>
</dd><dt><b>See Also:</b></dt><dd>proc - <a href="doc__util.html#doc::util::find_marker_indices">doc::util::find_marker_indices</a><br>
</dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td><blockquote>escapes out all square brackets</blockquote></td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>given a body of text and a text marker, returns a list
of position indices for each occurrence of the text
marker</blockquote><dl>
<dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>text</code><font color="red">*</font>
</td><td align="left">body of text to be searched through</td>
</tr><tr>
<td align="right">
<code>marker</code><font color="red">*</font>
</td><td align="left">the text-divider mark</td>
</tr>
</table>
</dd><dt><b>Returns:</b></dt><dd>list of indices of the position immediately preceding each
occurrence of the text marker; if there are no occurrences of the
text marker, returns a zero-element list</dd><dt><b>See Also:</b></dt><dd>namespace - <a href="doc">doc</a><br>
</dd><dd>proc - <a href="doc">doc::parse_file</a><br><a href="doc">doc::parse_namespace</a><br><a href="doc__util.html#doc::util::text_divider">doc::util::text_divider</a><br>
</dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td><blockquote>puts a space after all closing curly brackets, does not
add a space when brackets are already followed by a
space</blockquote></td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>used to sort the see list, which has structure {[name}
name type type url url \]</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>element1</code><font color="red">*</font>
</td><td align="left">the first of the two list elements to be
compared</td>
</tr><tr>
<td align="right">
<code>element2</code><font color="red">*</font>
</td><td align="left">the second of the two elements to be compared</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td></td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td></td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
This diff is collapsed.
This diff is collapsed.
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<a href="namespaces" target="mainFrame"><font size="+1" bold="">All Namespaces</font></a><br><table border="0" width="100%"><tr><td nowrap="nowrap" align="left">  <a href="doc" target="mainFrame">doc</a><br>
  <a href="doc__util.html" target="mainFrame">doc::util</a><br>
  <a href="form" target="mainFrame">form</a><br>
  <a href="request" target="mainFrame">request</a><br>
  <a href="util" target="mainFrame">util</a><br>
</td></tr></table><a href="../gen/generate-docs" target="mainFrame">Regenerate</a>
these pages.
<p>If you have not regenerated these pages before, you may have to
reset permissions on all files to be written as well as your
/doc/acs-templating/TclDocs directory.</p>
</body>
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2 class="title" align="center">ATS and CMS Tcl Procedure
Specifications</h2><table border="1" cellpadding="3" cellspacing="0" width="100%">
<tr bgcolor="#CCCCFF"><td width="100%"><font size="+2">Namespaces</font></td></tr><tr bgcolor="white"><td><a href="doc">doc</a></td></tr><tr bgcolor="white"><td><a href="doc__util.html">doc::util</a></td></tr><tr bgcolor="white"><td>
<a href="form">form</a><blockquote>Commands for managing dynamic templated
forms.</blockquote>
</td></tr><tr bgcolor="white"><td>
<a href="request">request</a><blockquote>The request commands provide a mechanism for managing
the query parameters to a page. The request is simply a special
instance of a form object, and is useful for the frequent cases
when data must be passed from page to page to determine display or
page flow, rather than perform a transaction based on user input
via a form.
<p>See: form <a href="">element</a>
</p>
</blockquote>
</td></tr><tr bgcolor="white"><td><a href="util">util</a></td></tr>
</table>
</body>
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace pagination</h2><blockquote>Procedures for paginating a datasource</blockquote><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>
<a href="#pagination::get_total_pages">pagination::get_total_pages</a><br><a href="#pagination::page_number_links">pagination::page_number_links</a><br><a href="#pagination::paginate_query">pagination::paginate_query</a><br>
</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><b>Public Methods:</b><br><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="pagination::get_total_pages" id="pagination::get_total_pages"><font size="+1" weight="bold">pagination::get_total_pages</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Gets the number of pages returned by a query PRE:
requires {$sql}</blockquote><dl><dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>db</code><font color="red">*</font>
</td><td align="left">A database handle</td>
</tr></table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="pagination::page_number_links" id="pagination::page_number_links"><font size="+1" weight="bold">pagination::page_number_links</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Generate HTML for navigating pages of a
datasource</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>page</code><font color="red">*</font>
</td><td align="left">The current page number</td>
</tr><tr>
<td align="right">
<code>total_pages</code><font color="red">*</font>
</td><td align="left">The total pages returned by the query</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="pagination::paginate_query" id="pagination::paginate_query"><font size="+1" weight="bold">pagination::paginate_query</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Paginates a query</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>sql</code><font color="red">*</font>
</td><td align="left">The sql query to paginate</td>
</tr><tr>
<td align="right">
<code>page</code><font color="red">*</font>
</td><td align="left">The current page number</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><p>
<b>Private Methods</b>:<br>
</p><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name="pagination::get_rows_per_page" id="pagination::get_rows_per_page"><font size="+1" weight="bold">pagination::get_rows_per_page</font></a></td></tr><tr><td><blockquote>Returns the number of rows per page</blockquote></td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="pagination::ns_set_to_url_vars" id="pagination::ns_set_to_url_vars"><font size="+1" weight="bold">pagination::ns_set_to_url_vars</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Converts an ns_set into a list of url
variables</blockquote><dl><dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>set_id</code><font color="red">*</font>
</td><td align="left">The set id</td>
</tr></table>
</dd></dl>
</td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
This diff is collapsed.
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace request</h2><blockquote>The request commands provide a mechanism for managing
the query parameters to a page. The request is simply a special
instance of a form object, and is useful for the frequent cases
when data must be passed from page to page to determine display or
page flow, rather than perform a transaction based on user input
via a form.</blockquote><p>Also see:</p><dl>
<dt>form</dt><dd><a href="">element</a></dd>
</dl><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>
<a href="#"></a><br><a href="#"></a><br><a href="#"></a><br><a href="#"></a><br><a href="#"></a><br>
</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><b>Public Methods:</b><br><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>Checks for any param errors. If errors are found, sets
the display template to the specified URL (a system-wide request
error page by default).</blockquote><dl>
<dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>url</code><font color="red">*</font>
</td><td align="left">The URL of the template to use to display error
messages. The special value { self} may be used to indicate that
the template for the requested page itself will handle reporting
error conditions.</td>
</tr></table>
</dd><dt><b>Returns:</b></dt><dd>1 if no error conditions exist, 0 otherwise.</dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>Create the request data structure. Typically called at
the beginning of the code for any page that accepts query
parameters.</blockquote><dl>
<dt><b>Options:</b></dt><dd><table><tr>
<td align="right"><code>params</code></td><td align="left">A block of parameter declarations, separated by
newlines. Equivalent to calling set_param for each parameter, but
requiring slightly less typing.</td>
</tr></table></dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>Declares a query parameter as part of the page request.
Validates the values associated with the parameter, in the same
fashion as for form elements.</blockquote><dl>
<dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>name</code><font color="red">*</font>
</td><td align="left">The name of the parameter to declare.</td>
</tr></table>
</dd><dt><b>Options:</b></dt><dd><table>
<tr>
<td align="right"><code>name</code></td><td align="left">The name of parameter in the query (may be
different from the reference name).</td>
</tr><tr>
<td align="right"><code>multiple</code></td><td align="left">A flag indicating that multiple values may be
specified for this parameter.</td>
</tr><tr>
<td align="right"><code>datatype</code></td><td align="left">The name of a datatype for the element values.
Valid datatypes must have a validation procedure defined in the
<tt>template::data::validate</tt> namespace.</td>
</tr><tr>
<td align="right"><code>optional</code></td><td align="left">A flag indicating that no value is required for
this element. If a default value is specified, the default is used
instead.</td>
</tr><tr>
<td align="right"><code>validate</code></td><td align="left">A list of custom validation blocks in the form {
name { expression } { message } \ name { expression } { message }
...} where name is a unique identifier for the validation step,
expression is a block to Tcl code that evaluates to 1 or 0, and
message is to be displayed to the user when the validation step
fails.</td>
</tr>
</table></dd><dt><b>See Also:</b></dt><dd>element::create - <a href=""></a><br>
</dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>Manually report request error(s) by setting error
messages and then calling is_valid to handle display. Useful for
conditions not tied to a single query parameter. The arguments to
the procedure may be any number of name-message
combinations.</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>name</code><font color="red">*</font>
</td><td align="left">A unique identifier for the error condition, which
may be used for layout purposes.</td>
</tr><tr>
<td align="right">
<code>msg</code><font color="red">*</font>
</td><td align="left">The message text associated with the
condition.</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>Retrieves the value(s) of the specified
parameter.</blockquote><dl>
<dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>name</code><font color="red">*</font>
</td><td align="left">The name of the parameter.</td>
</tr></table>
</dd><dt><b>Returns:</b></dt><dd>The value of the specified parameter.</dd>
</dl>
</td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
<property name="context">{/doc/acs-templating {Templating}} {ArsDigita Templating System, Content Management Tcl
Procedure Specifications}</property>
<property name="doc(title)">ArsDigita Templating System, Content Management Tcl
Procedure Specifications</property>
<master>
<body></body>
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace util</h2><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>The namespace util currently contains no public
methods.</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><p>
<b>Private Methods</b>:<br>
</p><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td><blockquote>a proc used for debugging, just prints out a value to
the error log</blockquote></td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>capitalizes the first letter of a string</blockquote><dl>
<dt><b>Returns:</b></dt><dd>returns formatted string</dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>escapes quotes and removes comment tags from a body of
commented text</blockquote><dl>
<dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>text</code><font color="red">*</font>
</td><td align="left"></td>
</tr></table>
</dd><dt><b>Returns:</b></dt><dd>text</dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>just takes a body of text and puts a space behind every
double {quote;} this is done so that the text body can be treated
as a list without causing problems resulting from list elements
being separated by characters other than a space</blockquote><dl>
<dd>
<b>Parameters:</b><table><tr>
<td align="right">
<code>text</code><font color="red">*</font>
</td><td align="left">req/none the body of text to be worked on</td>
</tr></table>
</dd><dt><b>Returns:</b></dt><dd>same text but with a space behind each quote; double quotes
that are already trailed by a space are unaffected</dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>takes a .adp template name and the name of the file to
be written and creates the {file;} also puts out a notice
before</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>template</code><font color="red">*</font>
</td><td align="left">the name of the template to be used in making the
file</td>
</tr><tr>
<td align="right">
<code>file_name</code><font color="red">*</font>
</td><td align="left">the name of the file to be created</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td>
<blockquote>takes an alphabetized list and an entry</blockquote><dl>
<dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>list</code><font color="red">*</font>
</td><td align="left">{let's see how this parses out} the alphabetized
list</td>
</tr><tr>
<td align="right">
<code>entry</code><font color="red">*</font>
</td><td align="left">req the value to be inserted</td>
</tr>
</table>
</dd><dt><b>Returns:</b></dt><dd>either the proper list index for an alphabetized insertion or
-1 if the entry is already in the list</dd>
</dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td><blockquote>used to compare two different elements in a list of
parsed data for public or private procs</blockquote></td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td><blockquote>uses ns_library to find the server root, may not always
be accurate because it essentially asks for the tcl library path
and strips off the last /tcl directory</blockquote></td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name=""></a></td></tr><tr><td></td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
<property name="context">{/doc/acs-templating {Templating}} {}</property>
<property name="doc(title)"></property>
<master>
<body>
<h2>Namespace widget</h2><blockquote>Procedures for generating and processing metadata form
widgets, editing attribute widgets</blockquote><h3>Method Summary</h3>
Listing of public methods:<br><blockquote>
<a href="#widget::param_element_create">widget::param_element_create</a><br>
</blockquote><h3>Method Detail</h3><p align="right">
<font color="red">*</font> indicates required</p><b>Public Methods:</b><br><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF"><a name="widget::param_element_create" id="widget::param_element_create"><font size="+1" weight="bold">widget::param_element_create</font></a></td></tr><tr><td>
<blockquote>Dipatches subprocs to generate the form elements for
setting an attribute widget param</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>form</code><font color="red">*</font>
</td><td align="left">Name of the form in which to generate the form
elements</td>
</tr><tr>
<td align="right">
<code>param</code><font color="red">*</font>
</td><td align="left">Name of the form widget param for which to
generate a form element</td>
</tr><tr>
<td align="right">
<code>order</code><font color="red">*</font>
</td><td align="left">The order that the param form widget will appear
in the form</td>
</tr><tr>
<td align="right">
<code>param_id</code><font color="red">*</font>
</td><td align="left">The ID of the form widget param</td>
</tr><tr>
<td align="right">
<code>default</code><font color="red">*</font>
</td><td align="left">The default value of the form widget param</td>
</tr><tr>
<td align="right">
<code>is_required</code><font color="red">*</font>
</td><td align="left">Flag indicating whether the form widget param is
optional or required</td>
</tr><tr>
<td align="right">
<code>param_source</code><font color="red">*</font>
</td><td align="left">The default source of the value of the form widget
param. One of literal, eval, query</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><p>
<b>Private Methods</b>:<br>
</p><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="widget::create_options_param" id="widget::create_options_param"><font size="+1" weight="bold">widget::create_options_param</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Create the options param form widget for adding/editing
metadata form widgets</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>form</code><font color="red">*</font>
</td><td align="left">The name of the form</td>
</tr><tr>
<td align="right">
<code>order</code><font color="red">*</font>
</td><td align="left">The order of placement of the form widget within
the form</td>
</tr><tr>
<td align="right">
<code>default</code><font color="red">*</font>
</td><td align="left">The default value of the form widget param
value</td>
</tr><tr>
<td align="right">
<code>is_required</code><font color="red">*</font>
</td><td align="left">A flag indicating whether the form widget param
value is mandatory</td>
</tr><tr>
<td align="right">
<code>param_source</code><font color="red">*</font>
</td><td align="left">The default param source for the form widget param
value (literal, query, eval)</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="widget::create_param_source" id="widget::create_param_source"><font size="+1" weight="bold">widget::create_param_source</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Create default param_source form widget for
adding/editing metadata form widgets</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>form</code><font color="red">*</font>
</td><td align="left"></td>
</tr><tr>
<td align="right">
<code>order</code><font color="red">*</font>
</td><td align="left">The order of placement of the form widget within
the form</td>
</tr><tr>
<td align="right">
<code>param_source</code><font color="red">*</font>
</td><td align="left">The default param source of the metadata widget
(literal, query, eval)</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="widget::create_param_type" id="widget::create_param_type"><font size="+1" weight="bold">widget::create_param_type</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Create default param_type form widget for
adding/editing metadata form widgets</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>form</code><font color="red">*</font>
</td><td align="left">The name of the form</td>
</tr><tr>
<td align="right">
<code>order</code><font color="red">*</font>
</td><td align="left">The order of placement of the form widget within
the form</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="widget::create_param_value" id="widget::create_param_value"><font size="+1" weight="bold">widget::create_param_value</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Create default param_value form widget for
adding/editing metadata form widgets</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>form</code><font color="red">*</font>
</td><td align="left">The name of the form</td>
</tr><tr>
<td align="right">
<code>order</code><font color="red">*</font>
</td><td align="left">The order of placement of the form widget within
the form</td>
</tr><tr>
<td align="right">
<code>is_required</code><font color="red">*</font>
</td><td align="left">A flag indicating whether the value of the form
widget param is mandatory</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="widget::create_text_param" id="widget::create_text_param"><font size="+1" weight="bold">widget::create_text_param</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Create default text param form widget for
adding/editing metadata form widgets</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>form</code><font color="red">*</font>
</td><td align="left">The name of the form</td>
</tr><tr>
<td align="right">
<code>default</code><font color="red">*</font>
</td><td align="left">The default value for the form widget param
value</td>
</tr><tr>
<td align="right">
<code>is_required</code><font color="red">*</font>
</td><td align="left">A flag indicating whether the value of the form
widget param is mandatory</td>
</tr><tr>
<td align="right">
<code>param_source</code><font color="red">*</font>
</td><td align="left">The deafult param source for the form widget param
value (literal, query, eval)</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="widget::create_values_param" id="widget::create_values_param"><font size="+1" weight="bold">widget::create_values_param</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Create the values param form widget for adding/editing
metadata widgets</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>form</code><font color="red">*</font>
</td><td align="left">The name of the form</td>
</tr><tr>
<td align="right">
<code>order</code><font color="red">*</font>
</td><td align="left">The order of placement of the form widget within
the metadata form</td>
</tr><tr>
<td align="right">
<code>default</code><font color="red">*</font>
</td><td align="left">The default value of the form widget param
value</td>
</tr><tr>
<td align="right">
<code>is_required</code><font color="red">*</font>
</td><td align="left">A flag indicating whether the form widget param
value is mandatory</td>
</tr><tr>
<td align="right">
<code>param_source</code><font color="red">*</font>
</td><td align="left">The default param_source for the form widget param
value (literal, query, eval)</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><table width="100%">
<tr><td width="100%" bgcolor="#CCCCFF">
<a name="widget::process_param" id="widget::process_param"><font size="+1" weight="bold">widget::process_param</font></a><br><small><i>  by Michael Pih</i></small>
</td></tr><tr><td>
<blockquote>Edits a metadata form widget parameter from the
form</blockquote><dl><dd>
<b>Parameters:</b><table>
<tr>
<td align="right">
<code>db</code><font color="red">*</font>
</td><td align="left">A database handle</td>
</tr><tr>
<td align="right">
<code>form</code><font color="red">*</font>
</td><td align="left">The name of the form</td>
</tr><tr>
<td align="right">
<code>order</code><font color="red">*</font>
</td><td align="left">The order of placement of the param form widgets
within the form</td>
</tr><tr>
<td align="right">
<code>content_type</code><font color="red">*</font>
</td><td align="left">The content type to which the attribute
belongs</td>
</tr><tr>
<td align="right">
<code>attribute_name</code><font color="red">*</font>
</td><td align="left">The name of the attribute</td>
</tr>
</table>
</dd></dl>
</td></tr>
</table><p align="right">
<font color="red">*</font> indicates required</p>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System API: Database Query}</property>
<property name="doc(title)">Templating System API: Database Query</property>
<master>
<body>
<h2>Database Query</h2><h3>Summary</h3><p>Utilize the results of a database query as a template data
source.</p><h3>Method</h3><pre>
query <em>name structure sql -db dbhandle
-startrow n
-maxrows n
-bind (set|list)
-eval { code }</em>
</pre><p>Perform a query and store the results in a local variable.</p><h3>Examples</h3><pre>
set db [ns_db gethandle]
# this will set a scalar named current_time
template::query current_time onevalue "select sysdate from dual" -db $db
# this will set a single array named user_info with a key for each column
template::query user_info onerow "select * from users
where user_id = 86" -db $db
# this will set an array for <em>each</em> row returned by the query
# the arrays will be named user_info:1, user_info:2, etc.
# the variable user_info:rowcount will be set with the total number of rows.
template::query user_info multirow "select * from users" -db $db
# this will set a list named emails
template::query emails onelist "select email from users" -db $db
# this will set a list of lists named user_info
template::query user_info multilist "select * from users" -db $db
# this will create a nested list of lists in the form
# { California { Berkeley { { Ralph Smith } { Doug Jones } } } \
# Minnestota { Minneapolis { { Ina Jaffe } { Silvia Pojoli } } } }
template::query persons nestedlist "
select state, city, first_name, last_name from users" \
-db $db -groupby { state city }
</pre><h3>Note(s)</h3><ul>
<li>Valid values for <tt>structure</tt> are <tt>onevalue, onerow,
multirow, onelist, nestedlist and multilist.</tt>
</li><li>
<tt>sql</tt> may be any valid SQL statement whose result set
has the appropriate dimensions for the desired
<tt>structure</tt>.</li><li>The <tt>db</tt> parameter is optional. If no parameter is
supplied, a handle will be requested to perform the query and then
released immediately.</li><li>The <tt>startrow</tt> and <tt>maxrows</tt> parameters are valid
only for multirow queries. They may be specified to limit the rows
from the query result that are included in the data source.</li><li>The <tt>eval</tt> parameter takes a block of Tcl code to
perform on each row of a multirow query as it is fetched from the
database. The code may refer to the <tt>row</tt> array to get and
set column values.</li><li>The <tt>bind</tt> option is valid only when using Oracle.</li>
</ul><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System API: Form Element}</property>
<property name="doc(title)">Templating System API: Form Element</property>
<master>
<body>
<h2>Form Element</h2><h3>Summary</h3><h3>Methods</h3><pre>
template::element create <em>form_name element_name \
-widget widget \
-datatype datatype \
-html { attribute value attribute value ... } \
-validate { \
name { expression } { message } \
name { expression } { message } \
... } \
-options { { label value } { label value } ... } \
-maxlength maxlength \
-value value \
-values { value value ... }
</em>
</pre><p>Append a new element to the specified form.</p><ul>
<li>The <tt>html</tt> switch may be used to include additional HTML
attributes in the <tt>input</tt>, <tt>select</tt>, or
<tt>textarea</tt> tag used to ultimately render the element.</li><li>The <tt>validate</tt> switch may be used to perform simple
custom validation of each element value. <tt>type</tt> is a keyword
for the type of validation being performed. This same keyword must
be referenced by the <tt><a href="../tagref/formerror.html">formerror</a></tt> tag to customize the
presentation and layout of the error message for this validation
step. <tt>expression</tt> must be a block of arbitrary Tcl code
that evaluates to 1 (valid) or 0 (not valid). The variable
<tt>$value</tt> may be used in the expression to reference the
element value. <tt>message</tt> is simply a string containing a
message to return to the user if validation fails. The variables
<tt>$value</tt> and <tt>$label</tt> may be used in the message to
reference the parameter value and label (or name if no label is
supplied).</li>
</ul><pre>
template::element set_properties <em>form_name element_name
</em>
</pre><pre>
template::element get_value <em>form_name element_name</em>
</pre><h3>Example</h3><pre>
template::element get_values <em>form_name element_name</em>
</pre><h3>Note(s)</h3><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System API: Form}</property>
<property name="doc(title)">Templating System API: Form</property>
<master>
<body>
<h2>Form</h2><h3>Summary</h3><p>Building dynamic forms with automated validation.</p><h3>Methods</h3><pre>
template::form create <em>name \
-html { attribute value attribute value }</em>
</pre><p>Initialize data structures for a dynamic form. This procedure
must be called before adding elements to the form.</p><ul><li>Additional attributes to include in the HTML form tag may be
specified with the <tt>html</tt> option.</li></ul><pre>
template::form is_request <em>name</em>
</pre><p>Boolean procedure for determining whether a submission is in
progress. If this procedure returns true, then an initial request
for the form is underway. The code for insert or add forms may thus
query for primary key value(s), and the code for update forms may
query for current data and set the value(s) of form elements
accordingly.</p><pre>
template::form is_valid <em>name</em>
</pre><p>Boolean procedure that returns true if a submission is in
progress <em>and</em> the submission is valid. Database or any
other transactions based on the form submission should only take
place after this procedure has been checked.</p><h3>Example</h3><h3>Note(s)</h3><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Object and API Reference}</property>
<property name="doc(title)">Object and API Reference</property>
<master>
<body>
<h2>Object and API Reference</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : API
Some of the API discussed here achieves functionality that the ACS
(ArsDigita Community System) provides, just in different ways. If
you have the ACS installed, you likely want to use that instead of
the <code>query</code> and <code>request</code> call presented
below.
<ul>
<li><a href="database">Database Query</a></li><li><a href="multirow">Mutirow Data Source</a></li><li><a href="request">Request</a></li><li><a href="form">Form</a></li><li><a href="element">Form Element</a></li>
</ul><hr><address><a href="mailto:christian\@arsdigita.com">Christian
Brechbühler</a></address><!-- Created: Thu Sep 21 15:32:06 EDT 2000 -->
Last modified: $Id: index.html,v 1.1.1.1 2001/03/13 22:59:27 ben
Exp $
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System API: Multirow}</property>
<property name="doc(title)">Templating System API: Multirow</property>
<master>
<body>
<h2>Multirow</h2><h3>Summary</h3><p>Access and modify rows and columns of a multirow data
source.</p><h3>Methods</h3><pre>
multirow <b>get</b><em>name index column</em>
</pre><blockquote>
<p>Get a particular column value or a reference to an entire
row.</p><ul>
<li>Rows are indexed starting with 1.</li><li>If a column name is omitted, this procedure will set
<tt>name</tt> to be a reference to an array containing the values
for the row specified by <tt>index</tt>.</li>
</ul>
</blockquote><pre>
multirow <b>set</b><em>name index column value</em>
</pre><blockquote><p>Set the value of a column in a specified row.</p></blockquote><pre>
multirow <b>size</b><em>name</em>
</pre><blockquote><p>Get the number of rows in the data source.</p></blockquote><pre>
multirow <b>create</b><em>name column [column ...]</em>
</pre><blockquote><p>Set up a new multirow data source. This is an alternative to
having <a href="/api-doc/proc-view?proc=db%5fmultirow">db_multirow</a> create the
data source.</p></blockquote><pre>
multirow <b>append</b><em>name value [value ...]</em>
</pre><blockquote><p>Add a row at the end of the data source. Extra values are
dropped, missing values default to the empty string</p></blockquote><pre>
multirow <b>map</b><em>name body</em>
</pre><blockquote><p>Evaluate <em>body</em> for each row of the data source, and
return a list with all results. Within the body, all columns of the
current row are accessible (and modifiable) as local variables.
(Not yet committed.)</p></blockquote><h3>Examples</h3><pre>
template::query foo multirow "select first_name, last_name from users"
<font color="green"># get the first name of the first user</font>
set first_name [multirow get foo 1 first_name]
<font color="green"># get a reference to the entire row</font>
multirow get foo 1
<font color="green"># this will the full name of the first user</font>
set full_name "$foo(first_name) $foo(last_name)"
</pre><h3>Note(s)</h3><ul><li>Use the <tt>eval</tt> option to template::query to modify
column values while building a data source from a multirow query
result.</li></ul><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System API: Page Request}</property>
<property name="doc(title)">Templating System API: Page Request</property>
<master>
<body>
<h2>Page Request</h2><h3>Summary</h3><p>Transform, validate and report errors in the query parameters
associated with a page request.</p><p>This API is an alternative to <code>ad_page_contract</code>
which should usually be preferred if you have ACS installed.</p><h3>Methods</h3><pre>
template::request create
</pre><p>Initialize the data structure to store request parameters.
Should be called at the start of any page that takes request
parameters.</p><pre>
template::request set_param <em>name
-datatype datatype
-multiple
-optional
-validate { { expression } { message } }</em>
</pre><p>Validates request parameter values and then sets a local
variable. Values are transformed if a transformation procedure
exists for the specified datatype (i.e. the components of a
<tt>date</tt> are assembled into a single structure).</p><ul>
<li>Options for <tt>datatype</tt> are the same as for form
elements.</li><li>The <tt>multiple</tt> switch indicates that more than one value
may be submitted. The local variable set by the procedure will be a
list.</li><li>The <tt>optional</tt> switch indicates that the parameter value
may be empty or missing. A value is assumed to be required if this
switch is not specified.</li><li>The <tt>validate</tt> switch may be used to perform simple
custom validation of each parameter value. <tt>expression</tt> must
be a block of arbitrary Tcl code that evaluates to 1 (valid) or 0
(not valid). The variable <tt>$value</tt> may be used in the
expression to reference the parameter value. <tt>message</tt> is
simply a string containing a message to return to the user if
validation fails. The variables <tt>$value</tt> and <tt>$label</tt>
may be used in the message to reference the parameter value and
label (or name if no label is supplied).</li>
</ul><pre>
template::request get_param <em>name</em>
</pre><p>Returns the value (or values if the <tt>multiple</tt> is used)
of the named parameter.</p><pre>
template::request is_valid <em>error_url</em>
</pre><p>Boolean procedure for determining whether any validation errors
occurred while setting request parameters.</p><ul><li>
<tt>error_url</tt> is the location of the template to use for
reporting request errors. The default is
<tt>/ats/templates/messages/request-error</tt> if no URL is
specified. To report request errors in the template of the page
itself, use <tt>self</tt> for the URL.</li></ul><h3>Example</h3><pre>
request create
request set_param state_abbrev -datatype keyword -validate {
{ regexp {CA|HI|NV} $value }
{ Invalid state abbreviation $value. }
}
request set_param start_date -datatype date
request set_param user_id -datatype integer -multiple
if { ! [request is_valid "/mytemplates/request-error"] } { return }
...
</pre><h3>Note(s)</h3><ul>
<li>Error reporting templates may reference the
<tt>requesterror</tt> array to access error messages for each
parameter.</li><li>The request API provides a simple mechanism for processing
request parameters. It is not intended as a replacement to
<tt>ad_page_contract</tt> for sites built on the ArsDigita
Community System.</li>
</ul><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System Appendix D: Parsing templates in
memory}</property>
<property name="doc(title)">Templating System Appendix D: Parsing templates in
memory</property>
<master>
<body>
<h2>Parsing Templates in Memory</h2><p>The templating system code is oriented towards parsing templates
stored in the file system, in conjunction with a Tcl script that is
also stored as a file. However, when the template is not actually
stored in the file system, you will need to parse it as a string in
memory. Two common situations in which this occurs are:</p><ul>
<li>Templates are stored in the database.</li><li>Templates are generated dynamically, possibly based in turn on
a "style" template. This is how ATS auto-generates forms.</li>
</ul><h3>The Parsing Process</h3><p>Whether the template is ultimately stored in a file or not, the
templating system follows the same basic process during the parsing
process:</p><ol>
<li>
<em>Prepare data sources.</em> Some Tcl code is evaluated to
prepare data sources (scalars, lists, multirow data structures) for
merging with the template. (For file-based templates the
interpreted code is cached in a procedure after the first
time).</li><li>
<em>Compile the template.</em>. The template markup is compiled
into a chunk of Tcl code that builds the page into a single output
string. (For file-based templates the resulting code is cached in a
procedure after the first time).</li><li>
<em>Evaluate the compiled template</em>. The template code is
evaluated in the same stack frame as the data source code, so that
all variables declared as data sources are directly available to
the template. The result of the evaluation step is a single string,
which normally is written to the connection.</li>
</ol><h3>How to Parse Templates in Memory</h3><p>The templating system provides a low-level API that allows you
to perform the three steps described above in the context of your
own code:</p><blockquote><pre>
<font color="green"># set up any number of data sources:</font>
set first_name George
query cars multirow "
select make, model from cars where first_name = :first_name"
<font color="green"># get the template. This may be a static string, be queried from the
# database, generated dynamically, etc.</font>
set template "
Hello \@first_name\@!
&lt;multiple name=cars&gt;
\@cars.rownum\@. \@cars.make\@ \@cars.model\@&lt;br&gt;
&lt;/multiple&gt;
"
<font color="green"># compile the template. The templating system takes the
# result of this step and wraps it in a proc so that it is
# bytecode-cached in the interpreter. You may wish to implement
# some sort of simple caching here as well.</font>
set code [template::adp_compile -string $template]
<font color="green"># evaluate the template code. Note that you pass a <em>reference</em>
# to the variable containing the code, not the value itself. The code
# is evaluated in the calling stack frame (by uplevel) so that
# the above data sources are directly accessible.</font>
set output [template::adp_eval code]
<font color="green"># now use the output however you wish</font>
</pre></blockquote>
Also see the "<a href="../demo/index.html#string">string</a>" demo.
<h3>Generating Templates from Other Templates</h3><p>In some cases, the template itself may be based on yet another
base template. For example, the templating system itself generates
form templates based on a generic "style" template. The generic
template primarily depends on a single data source,
<tt>elements</tt>, which references the element list for a
particular form object. A single <tt>multiple</tt>loop is used to
lay out the specific <tt>formwidget</tt> and <tt>formgroup</tt>
tags, along with labels and validation text, for the form. The
output of this first step is then rendered into HTML and returned
to the user.</p><p>Note that the generic "style" template contains templating tags
(<tt>formwidget</tt>, <tt>formgroup</tt>, <tt>if</tt> etc.) that
must be "protected" during the first step. The templating system
provides the <a href="../tagref/noparse.html"><tt>noparse</tt></a>
tag to do this.</p><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a><br>
Last modified: $Id: memory.html,v 1.1.1.1 2001/03/13 22:59:27 ben
Exp $
</body>
This diff is collapsed.
This diff is collapsed.
<property name="context">{/doc/acs-templating {Templating}} {Template Designer Guide}</property>
<property name="doc(title)">Template Designer Guide</property>
<master>
<body>
<h2>Designer Guide</h2><a href="">Templating System</a> : Designer Guide
<h3>Overview</h3><p>Templates are the primary means for separating the work of
developers and designers. A template is written by a designer and
consists largely of static HTML (or other markup). The template
author uses a small set of special markup tags to reference dynamic
data prepared by the developer.The tags allow authors to accomplish
four basic tasks that are not possible with standard HTML:</p><ul>
<li>Embed a dynamic variable in a template (<tt><a href="tagref/variable">var</a></tt>).</li><li>Repeat a template section for each object in a dynamic list of
objects (<tt><a href="tagref/multiple">multiple</a></tt>,
<tt><a href="tagref/grid">grid</a></tt>).</li><li>Output different template sections depending on the value of
one or more dynamic variables (<tt><a href="tagref/if">if</a></tt>).</li><li>Provide a mechanism for building complete pages from multiple
component templates (<tt><a href="tagref/include">include</a></tt>).</li>
</ul><p>A reasonably skilled template author should be able to implement
a template without any assistance from the developer, other than
assuring that the proper dynamic data is accessible.</p><h3>Concepts</h3><p>This section introduces the basic concepts underlying the use of
template tags in ACS 4.0.</p><h4>Variable Substitution</h4><p>Much like the mail merge feature of a word processor, template
authors must use special tags to position each piece of dynamic
data within the layout. Each template is associated with a data
dictionary that lists all available data sources.</p><p>See <a href="tagref/variable">Variable
Substitution</a>.</p><h4>Use of Components</h4><p>To speed development and ensure consistency of design, template
authors are encouraged to assemble pages from distinct component
templates that may be recycled in different contexts. One typical
practice is to build a "master" template for an entire section of a
site, with a common header, footer and sidebar layout. For each
page request, the "content" template is incorporated dynamically
into a specified area of the master template, usually a table
cell.</p><p>(graphic)</p><p>Another common practice is to build small reusable templates
that may be included in other templates as logical components. This
may be useful for common "widgets" such as search boxes or lists of
related links, as well as for building configurable portal pages
where users may assemble different types of content to their
liking.</p><p>(graphic)</p><p>See <a href="tagref/include"><tt>include</tt></a> and
<a href="tagref/master"><tt>master</tt></a>. See also <a href="guide/components">Building reusable layout components</a> and
<a href="guide/master">Using master templates</a>.</p><h4>Property Declarations</h4><p>Template authors need a simple mechanism for declaring
properties within the templates. The most common use of such
properties is for configuring elements of an enclosing master
template, such as the title, navigation links, and whether to
include a search box. The data dictionary specifies available
properties as well as the set of valid values when appropriate.</p><p>(graphic)</p><p>See <a href="tagref/property"><tt>property</tt></a>.</p><h4>Conditional Insertion</h4><p>Designers often need to tailor the layout depending on the
specific data being presented. For example, when presenting a list
of library books that a user has checked out, the designer might
want to highlight the overdue ones in red.</p><p>See <a href="tagref/if"><tt>if..else</tt></a>.</p><h4>Iteration</h4><p>Dynamic pages often present lists of values or records, each of
which typically represents the results of a database query.
Template authors must have a way to iterate over each value or
record in such a list and format it appropriately. In the simplest
scenario, the exact HTML is repeated with each iteration. However,
template authors often need to vary the design depending on the
context. For example:</p><ol>
<li><p>First and last items may be formatted differently from items in
between.</p></li><li><p>Special breaks may be required when a particular value changes.
For example, a query may return the name and office of all
employees in a company, and the designer may wish to insert a
subheading for each office.</p></li><li><p>Colors or patterns may alternate between items. For example, the
designer may want to have alternate between white and gray bands in
a table.</p></li>
</ol><p>To accomodate these type of scenarios, the template parser sets
some additional variables that the designer can reference to vary
the layout from item to item.</p><p>See <a href="tagref/multiple"><tt>multiple</tt></a>,
<a href="tagref/group"><tt>group</tt></a>, <a href="tagref/grid"><tt>grid</tt></a>.</p><a href="tagref/list"><!-- invisible<tt>list</tt>.--></a><h3>Notes</h3><ul>
<li><p>Template tags are processed by the server each time a page is
requested. The end result of this processing is a standard HTML
page that is delivered to the user. Users do not see template tags
in the HTML source code of the delivered page.</p></li><li>
<p>With normal usage, the use of dynamic tags tends to increase the
amount of whitespace in the final HTML as compared to the template.
This usually does not affect how browsers display the page.
However, if a page layout depends on the presence or absence of
whitespace between HTML tags for proper display, then special care
must be taken with dynamic tags to avoid adding whitespace.</p><p>When placed on a line by themselves, tags that are containers
for template sections (<tt>grid</tt>, <tt>if</tt>, and
<tt>multiple</tt>) will cause newlines to be added to the page at
the beginning and end of the section. This can be avoided by
crowding the start and end tags like so:</p><pre>
&lt;td&gt;&lt;if %x% eq 5&gt;&lt;img src="five.gif"&gt;&lt;/if&gt;
&lt;else&gt;&lt;img src="notfive.gif"&gt;&lt;/else&gt;&lt;/td&gt;
</pre><p>Note that this should not be done unless necessary, since it
reduces the legibility of the template to others who need to edit
the template later.</p>
</li><li><p>
<b>Caution:</b>   Do not write to the connection.
Specifically, if you must use the <code>&lt;% %&gt;</code> tag, do
not call <code>ns_puts</code>, because it will not work the same
way as in AOLserver's ADP pages.</p></li>
</ul><hr><address><a href="mailto:christian\@arsdigita.com">Christian
Brechbuehler</a></address><!-- Created: Mon Aug 14 11:53:07 EDT 2000 --><!-- hhmts start -->
Last modified: Mon Oct 2 14:12:08 EDT 2000 <!-- hhmts end -->
</body>
<property name="context">{/doc/acs-templating {Templating}} {Template System Guide}</property>
<property name="doc(title)">Template System Guide</property>
<master>
<body>
<h2>Programmer / Developer Guide</h2><a href="">Templating System</a> : Developer Guide
<h3>Mini How To</h3>
Start a Tcl page as usual with <code>ad_page_contract</code>. Be
sure to pass a <code>-properties</code> block; this signals the use
of templating. The tcl page should fill the data sources you
promised in the contract, and not write to the connection. At the
end of your tcl page, call <code>ad_return_template</code>. The
template system will look for an adp page with the file name stub
you indicate (defaulting to the same stub as the tcl page), process
that, and deliver it to the client. The adp page can use the
datasources defined in the tcl page.
<h3>Guide</h3><ol>
<li>User Guide</li><li style="list-style: none"><ul>
<li><a href="guide/index">Overview</a></li><li>Establishing data sources
<ul>
<li><a href="guide/data">Implementing data sources</a></li><li><a href="guide/document">Documenting data sources</a></li>
</ul>
</li><li>Creating templates
<ul>
<li><a href="guide/templates">Writing dynamic
templates</a></li><li><a href="guide/components">Building reusable layout
components</a></li><li><a href="guide/master">Using master templates</a></li><li><a href="guide/composite">Composite pages</a></li><li><a href="guide/skins">Presenting data in multiple styles
and formats</a></li><li><a href="guide/tcl">Mixing Tcl and HTML</a></li>
</ul>
</li><li>Managing forms
<ul>
<li><a href="guide/forms">Creating and populating
forms</a></li><li><a href="guide/form-templates">Customizing form
templates</a></li><li><a href="guide/form-process">Validating and processing
form submissions</a></li><li><a href="guide/wizards">Integrating forms into a
wizard</a></li><li><a href="guide/search">Implementing a search-and-select
form</a></li><li><a href="guide/form-widgets">Implementing custom
widgets</a></li><li><a href="guide/form-datatypes">Implementing custom data
types</a></li>
</ul>
</li><li>Handling errors
<ul><li>See the "contract", "error", and "state" <a href="demo/">demos</a>.</li></ul>
</li>
</ul></li><li>Object and API Reference
<ul>
<li><a href="api/database">Database Query</a></li><li><a href="api/multirow">Mutirow Data Source</a></li><li><a href="api/request">Request</a></li><li><a href="api/form">Form</a></li><li><a href="api/element">Form Element</a></li><li><a href="widgets">Form Widgets</a></li>
</ul>
</li><li><a href="tagref">Template Markup Tag Reference</a></li><li>Appendices
<ul>
<li><a href="demo/">Appendix A: Sample templates</a></li><li><a href="appendices/memory">Appendix B: Parsing templates
in memory</a></li>
</ul>
</li>
</ol><h3>API</h3>
After the script for a page is executed, acs-templating processes
the template, interpolating any data sources and executing the
special tags. The resulting HTML page is written to the connection
(i.e., returned to the user).
<h5><code><a href="/api-doc/proc-view?proc=ad%5freturn%5ftemplate">ad_return_template</a></code></h5>
Normally, does nothing at all. With the <code>-string</code> option
you get the resulting HTML page returned as a string.
<p>The optional <code>template</code> argument is a path to a page
(tcl/adp file pair). Note that you don't supply the ".tcl" or
".adp" extension. It is resolved by help of
<code>template::util::url_to_file</code> (with the current file
stub as reference path) and passed to
<code>template::set_file</code>, to change the name of the page
being served currently. If it starts with a "/", it is taken to be
a path relative to the server root; otherwise it is a filename
relative to the directory of the tcl script.</p><h5><code><a href="/api-doc/proc-view?proc=ad_page_contract">ad_page_contract</a></code></h5>
Normally, complaints about incorrect parameters are written
directly to the connection, and the script is aborted. With the
option <code>-return_errors</code> you can name a variable into
which to put any error messages as a list, and
<code>ad_page_contract</code> will return in any case. You can then
present the errors to the user in a templated page, consistent with
the look and feel of the rest of your service. If there's no
complaint, <code>ad_page_contract</code> won't touch the variable;
typically it will stay undefined.
<hr><address><a href="mailto:christian\@arsdigita.com">Christian
Brechbühler</a></address><!-- Created: Mon Aug 14 11:53:07 EDT 2000 -->
Last modified: $Id: developer-guide.html,v 1.3 2004/02/10 12:16:40
joela Exp $
</body>
This diff is collapsed.
<property name="context">{/doc/acs-templating {Templating}} {Commenting Tcl procedures for parsing}</property>
<property name="doc(title)">Commenting Tcl procedures for parsing</property>
<master>
<body>
<h2>Using comments to document Tcl procedures</h2><b>Templating System</b><h3>Text divisions, grouping</h3><i>&lt; blah blah &gt;</i> The Tcl proc parser relies on three main
text markers to divvy the Tcl library file into neat compartments:
namespace, procedure and directive. Each of these divisions has its
own text marker(s). In the end, your Tcl file should look somthing
like this:
<blockquote><pre><code><tt>
[------------------------------------------------------]
[------ <i>ignored text at beginning of file</i> -----------]
[------------------------------------------------------]
# <font color="red">\@namespace</font><i>&lt;name&gt;</i><i>&lt;description of namespace&gt;</i>
# <i>&lt;continued description&gt;</i>
# <font color="red">\@author</font><i>&lt;name of the primary author for this namespace&gt;</i>
# <font color="red">\@see</font><i>&lt;type of reference, like <b>proc</b>, <b>namespace</b>, <b>url</b>, or other&gt;</i><i>&lt;full name of reference&gt;</i><i>&lt;url of reference&gt;</i>
# <font color="red">\@see</font> ... <i>&lt;more references&gt;</i>
# (<font color="red">\@public</font>|<font color="red">\@private</font>) <i>&lt;name&gt;</i><i>&lt;description of procedure&gt;</i>
# <i>&lt;continued description&gt;</i>
# <font color="red">\@param</font><i>&lt;name&gt;</i><i>&lt;default value&gt;</i><i>&lt;description&gt;</i>
# <i>&lt;continued description&gt;</i>
# <font color="red">\@param</font> ... <i>&lt;info for other paramaters&gt;</i>
# <font color="red">\@option</font><i>&lt;name&gt;</i><i>&lt;default value&gt;</i><i>&lt;description&gt;</i>
# <i>&lt;continued description&gt;</i>
# <font color="red">\@option</font> ... <i>&lt;info for other options&gt;</i>
# <font color="red">\@author</font><i>&lt;name of author&gt;</i>
# <font color="red">\@return</font><i>&lt;description of return variable&gt;</i>
# <font color="red">\@see</font><i>&lt;just like the namespace \@see directive&gt;</i>
[------------------------------------------------------]
[---------- <i>source text for procedure</i> ---------------]
[------------------------------------------------------]
# <font color="red">\@public</font> or <font color="red">\@private</font> ... <i>&lt; more procedures within the same namespace &gt;</i>
# <font color="red">\@namespace</font> ... <i>&lt;other namespaces&gt;</i>
</tt></code></pre></blockquote>
Note that comment lines are indented to indicate the manner in
which they should be grouped only, and that there is no required
spacing scheme for comments.
<p>Use of these directive markers is largely straightforward, but a
more in depth guideline of how the markers guide parsing may help
those documenting their own work:</p><blockquote>
<b>the \@namespace marker</b><ul>
<li>
<code><b>\@namespace</b></code> is used to indicate the starting
point of all text -- code and comments -- related to the procedures
contained within that namespace. All text between one
<code>\@namespace</code> marker and the next is parsed out as either
Tcl proc source text or commentary of some sort</li><li>the body of text that falls between two <code>\@namespace</code>
markers is divided into sections identified by</li>
</ul><b>the \@public/private markers</b><ul>
<li>although this convention is in no way enforced, each Tcl
procedure should be prefaced with an <code>\@private</code> marker
if the procedure is meant only for internal package use, or with an
<code>\@public</code> marker if the proc is intended to be a CMA,
ATS, or ACS Content Repository developer api</li><li>any text that falls between one \@public/private marker and the
next <code>proc &lt;procedure name&gt;</code> call will be parsed
out as commentary text; all text after the <code>proc</code>
command but before the next <code>\@private</code> or
<code>\@public</code> marker is recorded as source code</li>
</ul><b>the directive markers</b><br>
The commentary text that precedes a Tcl <code>proc</code> command
should contain a list of directives identified by these markers:
<ul>
<li><code>\@author</code></li><li><code>\@param</code></li><li><code>\@option</code></li><li><code>\@return</code></li><li><code>\@see</code></li>
</ul>
The parser requires no specified ordering or grouping of these
directives. Note: there should be one <code>\@param</code> or
<code>\@option</code> directive marker for each parameter and option
accepted by Tcl procedure. For the <b>\@option</b> and
<b>\@parameter</b> markers, please follow one of the following
formats, depending on whether or not the parameter or option you
are detailing has a default value:
<blockquote>with a default value:
<blockquote><code># \@(param|option) <i>&lt;parameter name&gt;</i>
{default <i>&lt;description of default value&gt;</i>}
<i>&lt;description or explanation&gt;</i>
</code></blockquote>
for required parameters:
<blockquote><code># \@param <i>&lt;parameter name&gt;</i><i>&lt;description or explanation&gt;</i>
</code></blockquote>
</blockquote>
Note that the literal curly brackets with the word
<b><i>default</i></b> are required to include any information about
the option or parameter's default values. When default-value
information is not included, the entry value will be marked as
<i>required</i> if it is a parameter, or display no information if
it is an option.
<p>For example: the fictional procedure grant_permission might be
preceded by these comments:</p><blockquote><pre><code># \@public grant_permission
# checks for whether or not a user has the privilege
# to manipulate an object in a specific manner
# \@param user_id id of the user to be granted the privilege
# \@param object_id id of the object which the user has been
# granted privilege to manipulate
# \@param privilege_id {default defaults to read-write-edit on the object}
# id of the privilege specifying
# what actions the user can perform upon the object
# \@option granter_id {default taken from the current user's id} id of the user granting the privilege
# \@option alert_admin_email email of an admin to be alerted
# \@see namespace util util.html
</code></pre></blockquote>
In the above example <code>user_id</code> and
<code>object_id</code> would be marked as required,
<code>alert_admin_email</code> would show no default-value
description, and <code>granter_id</code> and
<code>privilege_id</code> would show the the default info from
above.
<p>On to <b>\@see</b> directive markers:</p><blockquote># \@see <i>&lt;type of reference&gt;</i><i>&lt;name of
reference&gt;</i><i>&lt;url of reference&gt;</i>
</blockquote>
Indicating the url of the reference is made somewhat simple because
all namespaces will be described within their own static html page,
and all procedure information is anchor-referenced:
<blockquote><pre><code>
# \@see namespace util util.html
# \@see proc template::multirow::create multiow.html#template::multirow::create
# \@see url <i>&lt;a picture of wally my dog&gt;</i> http://my.page.net/dogs/wally.jpg
# \@see proc doc::util::eat_chicken
</code></pre></blockquote>
If you are referring to a namespace or procedure (use
<code>proc</code> for the reference type), the url value is
optional as long as you use the <b>full</b> and <b>completely
qualified</b> name of the namespace or procedure.</blockquote><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Building Reusable Template
Components}</property>
<property name="doc(title)">Templating System User Guide: Building Reusable Template
Components</property>
<master>
<body>
<h2>Building Reusable Template Components</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<p>Most page layouts can be separated into smaller components, many
of which may appear in different contexts throughout a site.
Examples include:</p><ul>
<li>A box or section of the page listing contextual links related
to the contents of the page.</li><li>A list of comments on the contents of the page.</li><li>A search box, user poll, or other small embedded form.</li><li>Reports and other administrative pages, where the employee may
wish to assemble multiple panels of information on a single
page.</li><li>Many popular portal sites allow users to customize their home
pages by choosing and arranging a set of small layout components
within a table grid.</li>
</ul><p>The templating system makes it easy to build <a href="composite">reusable components</a> for any of the above
scenarios. The basic process is to build a container template,
which delineates the skeletal layout of the page. Component
templates may then be placed in the container template with the
<tt>include</tt> tag. The container may pass arguments to the
components as needed for personalization or any other purpose.</p><!--
<h3>Building the Container Template</h3>
<h3>Including Component Templates</h3>
--><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Composite Page}</property>
<property name="doc(title)">Templating System User Guide: Composite Page</property>
<master>
<body>
<h2>Assembling a Page from Components</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : <a href="">User
Guide</a> : Composite
<p>A typical page served to a browser is made up from several
component pages. The idea is to have reusable parts (widgets,
skins), a bit like in a programming language where code that may be
used more than once makes up a procedure. The complete page may
have the following structure.</p><center><table cellpadding="5" cellspacing="0"><tr><td bgcolor="#FFCCCC">
<b>master</b><table cellpadding="5" cellspacing="8">
<tr><td bgcolor="#CCCCFF" valign="top"><b>top</b></td></tr><tr><td height="120" bgcolor="#CCCC99" valign="top">
<b>root (main)</b><p> </p><table cellpadding="5" cellspacing="8"><tr><td width="120" bgcolor="#CCFFCC" valign="top"><b>widget</b></td></tr></table>
</td></tr><tr><td bgcolor="#99CCFF" valign="top"><b>bottom</b></td></tr>
</table>
</td></tr></table></center><p>The "root" page includes the "widget" and wraps itself in the
"master". That page in turn includes the "top" and "bottom".</p><h3>Overall structure</h3><p>The parts are put together with the <code>&lt;<a href="../tagref/include.html">include</a>&gt;</code> tag (in the diagram
below, black links going right) and the <code>&lt;<a href="../tagref/master.html">master</a>&gt;</code> tag (brown link going
left); and the concept is similar to a procedure call. The
structure of the composite page looks like this as a graph.</p><center><table cellpadding="0" cellspacing="0" border="0">
<tr>
<td colspan="10" rowspan="3"></td><th colspan="7">root</th>
</tr><tr><td><img src="/image/clear.gif" width="1" height="5"></td></tr><tr>
<td bgcolor="#CCCC99"> code </td><td width="1"><img src="/images/clear.gif"></td><td bgcolor="#CCCC99" colspan="5"> template </td>
</tr><tr>
<td colspan="12"></td><td><img src="/images/clear.gif" width="20" height="20"></td><td bgcolor="#990000" width="1"><img src="/images/clear.gif" width="1" height="20"></td><td><img src="/images/clear.gif" width="20" height="20"></td><td bgcolor="#000000" width="1"><img src="/images/clear.gif" width="1" height="20"></td><td><img src="/images/clear.gif" height="20"></td>
</tr><tr>
<td colspan="3" rowspan="2"></td><td colspan="11" height="1" bgcolor="#990000">
<img src="/images/clear.gif" width="1" height="1"><!-- no space-->
</td><td height="1"><img src="/images/clear.gif" width="1" height="1"></td><td colspan="5" height="1" bgcolor="#000000"><img src="/images/clear.gif" width="1" height="1"></td>
</tr><tr>
<td bgcolor="#990000" width="1"><img src="/images/clear.gif" width="1" height="20"></td><td colspan="15"></td><td bgcolor="#000000" width="1"><img src="/images/clear.gif" width="1" height="20"></td>
</tr><tr>
<th>master</th><td><img src="/images/clear.gif" width="8"></td><td bgcolor="#FFCCCC"> code </td><td width="1"><img src="/images/clear.gif"></td><td bgcolor="#FFCCCC" colspan="5"> template </td><td colspan="9"></td><td bgcolor="#CCFFCC"> code </td><td width="1"><img src="/images/clear.gif"></td><td bgcolor="#CCFFCC"> template </td><td><img src="/images/clear.gif" width="8"></td><th>widget</th>
</tr><tr>
<td colspan="4" rowspan="4"></td><td rowspan="4"><img src="/images/clear.gif" width="20" height="20"></td><td bgcolor="#000000" width="1" rowspan="3"><img src="/images/clear.gif" width="1" height="20"></td><td rowspan="2"><img src="/images/clear.gif" width="20" height="20"></td><td bgcolor="#000000" width="1"><img src="/images/clear.gif" width="1" height="20"></td><td><img src="/images/clear.gif" height="20"></td>
</tr><tr><td bgcolor="#000000" colspan="13"><img src="/images/clear.gif" width="1" height="1"></td></tr><tr>
<td colspan="13" height="8"><img src="/images/clear.gif"></td><td rowspan="3" bgcolor="#000000"><img src="/images/clear.gif"></td>
</tr><tr><td colspan="7" bgcolor="#000000"><img src="/images/clear.gif"></td></tr><tr>
<td colspan="11"></td><td bgcolor="#000000" height="20"><img src="/images/clear.gif"></td>
</tr><tr>
<td colspan="10" rowspan="3"></td><td bgcolor="#CCCCFF"> code </td><td width="1"><img src="/images/clear.gif"></td><td bgcolor="#CCCCFF" colspan="5"> template </td><td rowspan="3"><img src="/images/clear.gif" width="8"></td><td bgcolor="#99CCFF"> code </td><td width="1"><img src="/images/clear.gif"></td><td bgcolor="#99CCFF"> template </td>
</tr><tr><td><img src="/image/clear.gif" width="1" height="5"></td></tr><tr>
<th colspan="7">top</th><th colspan="3">bottom</th>
</tr>
</table></center><p>Any (sub)page can have 0 or 1 master and 0 or more included
pages. Each page has its own <em>separate</em> scope for variables.
Arguments can be passed to dependent pages as attributes to
<code>&lt;inlcude&gt;</code>, or as properties to
<code>&lt;master&gt;</code>. The directed graph of pages will often
be be acyclic, as in the example, but this is not required.</p><h3>Evaluation Order</h3><p>Sometimes it is of interest in which order the different parts
are evaluated. The "code" always runs first, followed by the
template. The <code>&lt;inlcude&gt;</code> tag causes the subpage
to be evaluated at this point of the template, and the rest of the
including template is evaluated after that's done. This is like a
procedure call. In contrast, the <code>&lt;master&gt;</code> tag is
deferred until the whole slave page ("root" in the example) is
done. For our example, the following order results.</p><center><table>
<tr>
<td colspan="3" bgcolor="#CCCC99"><b>root.tcl</b></td><td></td>
</tr><tr>
<td colspan="3" bgcolor="#CCCC99"><b>root.adp</b></td><td>(beginning and middle)</td>
</tr><tr>
<td rowspan="2" width="15" bgcolor="#CCCC99"> </td><td colspan="2" bgcolor="#CCFFCC"><b>widget.tcl</b></td><td></td>
</tr><tr>
<td colspan="2" bgcolor="#CCFFCC"><b>widget.adp</b></td><td></td>
</tr><tr>
<td colspan="3" bgcolor="#CCCC99"><b>root.adp</b></td><td>(end)</td>
</tr><tr>
<td rowspan="8" width="15" bgcolor="#CCCC99"> </td><td colspan="2" bgcolor="#FFCCCC"><b>master.tcl</b></td><td></td>
</tr><tr>
<td colspan="2" bgcolor="#FFCCCC"><b>master.adp</b></td><td>(beginning)</td>
</tr><tr>
<td rowspan="2" width="15" bgcolor="#FFCCCC"> </td><td bgcolor="#CCCCFF"><b>top.tcl</b></td><td></td>
</tr><tr>
<td bgcolor="#CCCCFF"><b>top.adp</b></td><td></td>
</tr><tr>
<td colspan="2" bgcolor="#FFCCCC"><b>master.adp</b></td><td>(middle, containing <code>&lt;slave&gt;</code> tag)</td>
</tr><tr>
<td rowspan="2" width="15" bgcolor="#FFCCCC"> </td><td bgcolor="#99CCFF"><b>bottom.tcl</b></td><td></td>
</tr><tr>
<td bgcolor="#99CCFF"><b>bottom.adp</b></td><td></td>
</tr><tr>
<td colspan="2" bgcolor="#FFCCCC"><b>master.adp</b></td><td>(end)</td>
</tr>
</table></center><p>Here we assume the ACS/Tcl situation, where the "code" is a tcl
script in a .tcl file. The template is a .adp file.</p><h3>Variants of Page Nodes</h3><p>The graph of the overall structure has five nodes, shown as a
code/template pair. This is the standard situation, where the
"code" part sets up datasources and the template uses them. In some
situations, the following facility can help to reduce duplication
or to handle special situations more effectively.</p><p>The "code" part can divert to another page by calling
<code>template::set_file</code> to modify the file name stub of the
page being processed. For convenience,
<code>ad_return_template</code> can be used with the same effect;
it is a wrapper for <code>template::set_file</code>, and it
supplies the current file as the reference path. Neither affects
the flow of control; the script runs to completion. If at the end
the name is changed, the template of the original page is not used;
instead the new page is processed, code first, then template. As
that page's code can call <code>set_file</code> again, we get the
following picure.</p><center><table cellspacing="0" cellpadding="0" border="0">
<tr>
<td bgcolor="#FFCC99">code A</td><td width="1"><img src="/images/clear.gif"></td><td align="right"><font color="gray">(template A
ignored)</font></td>
</tr><tr><td align="center"><img src="down.gif" width="7" height="15"></td></tr><tr>
<td bgcolor="#FFCC99">code B</td><td></td><td align="right"><font color="gray">(template B
ignored)</font></td>
</tr><tr><td align="center"><img src="down.gif" width="7" height="15"></td></tr><tr><td align="center">...</td></tr><tr><td align="center"><img src="down.gif" width="7" height="15"></td></tr><tr>
<td bgcolor="#FFCC99" align="center">code Z</td><td></td><td bgcolor="#FFCC99" align="center">template Z</td>
</tr>
</table></center><p>This assumes page "A" was originally wanted. An arrow (<img src="down.gif" width="7" height="15" align="top">) exits from code
which calls <code>template::set_file</code> (directly or through
<code>ad_return_template</code>). All scripts and the template are
executed in the <em>same</em> scope, i.e., they share
variables.</p><p>Furthermore either of the final files can be omitted if it is
not needed, giving three basic possibilities.</p><center><table cellspacing="0" cellpadding="0" border="0">
<tr>
<td width="50">a)</td><td bgcolor="#FFCC99" align="center">code</td><td width="1"><img src="/images/clear.gif"></td><td bgcolor="#FFCC99" align="center">template</td>
</tr><tr><td> </td></tr><tr>
<td>b)</td><td><font color="gray">(no code)</font></td><td></td><td bgcolor="#FFCC99" align="center">template</td>
</tr><tr><td> </td></tr><tr>
<td>c)</td><td bgcolor="#FFCC99" align="center">code</td><td></td><td><font color="gray">(no template)</font></td>
</tr>
</table></center><p>It is an error to omit both parts; this is a special case
intended to speed up debugging.</p><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Data Sources}</property>
<property name="doc(title)">Templating System User Guide: Data Sources</property>
<master>
<body>
<h2>Implementing Data Sources</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<p>Data sources are implemented in a Tcl script using regular Tcl
variables, lists and arrays. The templating system includes a set
of procedures to simplify the construction of data sources from
relational database queries.</p><h3>The Structure of Data Sources</h3><p>The templating system can manipulate four basic types of
structures as data sources:</p><table cellspacing="0" cellpadding="4" border="1">
<tr>
<td><tt>onevalue</tt></td><td>A simple scalar, such as a user's first name or the total due
on a purchase order.</td>
</tr><tr>
<td><tt>onelist</tt></td><td>A list of simple scalars.</td>
</tr><tr>
<td><tt>onerow</tt></td><td>A one-row data table, with values in one or more columns.</td>
</tr><tr>
<td><tt>multirow</tt></td><td>A multi-row, multi-column data table.</td>
</tr>
</table><h3><tt>onevalue</tt></h3><p>
<tt>onevalue</tt> data sources are implemented simply by setting
a Tcl variable:</p><code>set name "Walter Cronkite"</code><p>The <tt>query</tt> procedure may be used to set a onevalue data
source based on a database query:</p><code>query name onevalue "select name from users where user_id =
123"</code><p>You can embed a <tt>onevalue</tt> data source in a template with
simple <a href="../tagref/variable.html">variable
substitution</a>.</p><h3><tt>onerow</tt></h3><p>
<tt>onerow</tt> data sources are implemented as Tcl arrays:</p><code>set name(first_name) Walter<br>
set name(last_name) Cronkite</code><p>The <a href="../api/database.html"><tt>query</tt></a> procedure
may be used as a convenient way to store the result of a one-row
database query into an array:</p><pre>
query name onerow "
select
first_name, last_name
from
users
where
user_id = 123"
</pre><p>You can embed references to column values of a <tt>onerow</tt>
data source in a template with simple <a href="../tagref/variable.html">variable substitution</a>.</p><h3><tt>onelist</tt></h3><p>
<tt>onelist</tt> data sources are implemented by creating a Tcl
list:</p><pre>
set names [list "Walter" "Fred" "Susy" "Frieda"]
</pre><p>The <tt>query</tt> procedure may be used to set a onelist data
source based on a one-column database query:</p><code>query name onevalue "select name from users"</code><p>You can iterate over a <tt>onelist</tt> data source in a
template with the <a href="../tagref/list.html">list</a> tag.</p><h3><tt>multirow</tt></h3><p>
<tt>multirow</tt> data sources are not represented by a single
Tcl data structure. As such the templating system includes a
special API for constructing and manipulating them.</p><pre>
multirow create cars make model year
multirow append cars "Toyota" "Camry" "1996"
multirow append cars "Volvo" "960" "1995"
</pre><p>The <a href="../api/database.html"><tt>query</tt></a> procedure
may be used as a convenient way to store the result of a multi-row,
multi-column database query into a <tt>multirow</tt> data
source:</p><pre>
query name multirow "
select
make, model, year
from
cars"
</pre><p>You can iterate over a <tt>multirow</tt> data source in a
template with the <a href="../tagref/multiple.html">multiple</a>
tag.</p><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Documenting Data
Sources}</property>
<property name="doc(title)">Templating System User Guide: Documenting Data
Sources</property>
<master>
<body>
<h2>Documenting Data Sources</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<p>Effective coordination between the developer and designer is one
of the major challenges of any publishing team. The templating
system provides a set of simple documentation directives so that
developer comments on data sources can be extracted from Tcl
scripts and summarized for non-technical members of the publishing
team automatically.</p><p>To take advantage of this capability, the developer must
structure comments on a datasource in the following way:</p><pre>
# \@datasource cars multirow
# The cars owned by a user.
# \@column make The make of the car, i.e. Toyota
# \@column model The model of the car, i.e. Camry
# \@column year The year of manufacture
# \@datasource name onevalue
# the name of the user
# \@data_input add_entry form
# a form for adding entries to user's address book
# \@input first_names text
# entry subject's first and middle names
# \@input last_name text
# \@input title text form of address for entry subject
# \@input birthday date birthdate w/ "MONTH DD YYYY" format
# \@input gender radio
# either "m" for male or "f" for female
</pre><p>A few formatting guidelines:</p><ul>
<li>all datasources (onevalues, onelists, multilists, multirows)
are documented with the datasource directive, their name, the type
of datasource, and then necessary comments:</li><li style="list-style: none"><blockquote><code># \@datasource <i>name</i> &lt;<i>type of
datasource</i>&gt; <i>comments</i>
</code></blockquote></li><li>multirow datasources are followed with a series of column
directives, column names, and associated explanations:</li><li style="list-style: none"><blockquote><code># \@column <i>name</i><i>comments</i>
</code></blockquote></li><li>forms are documented with the data_input directive, and are
also followed with a series of input directives with the name and
type of input widgets, and necessary comments:</li><li style="list-style: none">
<blockquote><code># \@data_input <i>name</i> form <i>comments</i> #
\@input <i>name</i> &lt;<i>type of form entry</i>&gt;
<i>comments</i>
</code></blockquote>
Possible form entry types include text (or textentry), date,
checkbox, radio, select, multiselect and textbox</li>
</ul><p>Once the templates have been enabled, the designer can simply
visit the URL from which the page will be served, substituting
<tt>acs</tt> with the <tt>dat</tt> extension.</p><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Custom Data Types}</property>
<property name="doc(title)">Templating System User Guide: Custom Data Types</property>
<master>
<body>
<h2>Custom Data Types</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Validating and Processing Form
Submissions}</property>
<property name="doc(title)">Templating System User Guide: Validating and Processing Form
Submissions</property>
<master>
<body>
<h2>Validating and Processing Form Submissions</h2><p>
<b>Important Note:</b> The <tt><a href="http://openacs.org//api-doc/proc-view?proc=ad%5fform">ad_form</a></tt>
function has been written to be a more consistent, easier way to
create and manage dynamic forms. Behind the scenes it uses the
templating system's form builder, but it hides much of its
complexity. You should definitely look at it and at the pages that
use it in the survey package.</p><p>The templating system provides a simple infrastructure for
validating form submissions. The typical life-cycle of a form is as
follows:</p><ol>
<li>The user makes the initial request for a page containing a
form. The code associated with the page creates the form (with the
<tt>form create</tt> command) and populates it with elements.</li><li>The developer may use the <tt>form is_request</tt> command to
encapsulate any special initialization (for example, setting a
primary key value for an <b>Add</b> form, or retrieving current
values for an <b>Edit</b> form).</li><li>The <tt>formtemplate</tt> tag is used to enclose the form
template. This tag is responsible for generating the appropriate
HTML <tt>FORM</tt> tag in the final output. The
<tt>formtemplate</tt> tag also embeds a special hidden variable in
the form for the purpose of identifying incoming submissions.</li><li>By default, the <tt>formtemplate tag</tt> sets the
<tt>ACTION</tt> attribute of the <tt>FORM</tt> tag to the
<em>same</em> URL as that of the form itself. The submission is
therefor processed within the framework of the same code that was
used to create the form.</li>
</ol><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Customizing Form
Templates}</property>
<property name="doc(title)">Templating System User Guide: Customizing Form
Templates</property>
<master>
<body>
<h2>Customizing Form Templates</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<p>The templating system allows the designer to have full control
over the layout of a dynamic form.</p><h3>Starting with an autogenerated form template</h3><p>In most cases, the simplest way for the designer to get started
is to edit the autogenerated form template. This template will have
all the necessary <tt>formwidget</tt> and <tt>formgroup</tt>
tags.</p><h3>Using form metadata</h3><p>The designer must take care that all form elements created by
the developer in the code file are also represented in the
associated template. Checking the template against the form
metadata is the best means to ensure that elements are not
omitted.</p><p>Viewing of form metadata is not implemented yet.</p><!--
<h3>Working with <tt>input</tt> and <tt>select</tt> widgets</h3>
<p></p>
<h3>Working with groups of checkboxes or radio buttons</h3>
<p></p>
--><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Custom Form Widgets}</property>
<property name="doc(title)">Templating System User Guide: Custom Form Widgets</property>
<master>
<body>
<h2>Custom Form Widgets</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<p>Form widgets are implemented as tcl procs that output the html
to generate the form element. The tcl proc must be in the
template::widget namespace. So the proc for the search widget is
called template::widget::search. The code that generates the built
in widgets is in packages/acs-templating/tcl/widget-procs.tcl.</p><p>If the data from the form widget needs to be formatted or
processed a tcl proc is created in the template::data::transform
namespace. For example, templatete::data::transform::search. This
takes the input from the user and processes it to be returned to
the tcl code handling the form.</p><hr>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Creating and Populating
Forms}</property>
<property name="doc(title)">Templating System User Guide: Creating and Populating
Forms</property>
<master>
<body>
<h2>Creating and Populating Forms</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<p>This document outlines the steps necessary to build a dynamic
form in Tcl code.</p><p>
<b>Important Note:</b> The <tt><a href="http://openacs.org//api-doc/proc-view?proc=ad%5fform">ad_form</a></tt>
function has been written to be a more consistent, easier way to
create and manage dynamic forms. Behind the scenes it uses the
templating system's form builder, but it hides much of its
complexity. You should definitely look at it and at the pages that
use it in the survey package.</p><h3>Create a form</h3><p>Use the <tt>form create</tt> command to initialize a form:</p><pre>
form create add_user
</pre><p>See the <a href="../api/form.html">form API</a> for optional
parameters to this command.</p><h3>Add elements</h3><p>Once the form is created, use the <tt>element create</tt>
command to add elements to it:</p><pre>
element create add_user first_name -datatype text \
-label "First Name" \
-html { size 30 }
</pre><p>In auto-generated forms, elements appear in the order they were
created. See the <a href="../api/element.html">element API</a> for
optional parameters to this command.</p><h3>Set values</h3><p>Self-validating forms should check whether a request or
submission is currently being processed. If a request is being
processed, then form elements may need to be initialized with their
appropriate values.</p><pre>
if { [template::form is_request add_user] } {
set db [ns_db gethandle]
set query "select ad_template_sample_users_seq.nextval from dual"
template::query user_id onevalue $query -db $db
ns_db releasehandle $db
template::element set_properties add_user user_id -value $user_id
}
</pre><p>This may also be done using the <tt>value</tt> option to
<tt>element create</tt>. In this case the value is set separately
to avoid the additional database query during a submission.</p><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Overview}</property>
<property name="doc(title)">Templating System User Guide: Overview</property>
<master>
<body>
<h2>Overview</h2><a href="../index.html">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<p>This document provides a brief introduction to the design of the
templating system and the process of building dynamic pages with
the templating system.</p><h3>Introduction</h3>
The templating system solves a clear business need: providing a
system for efficient collaboration between designers and developers
on building a web site. Writing a dynamic web page requires writing
application logic that retrieves data from a database and HTML
markup that presents this data in a readable form for the user. In
practice on production sites, this requires collaboration between
designers sensitive to issues of usability and the user experience
and developers who are sensitive to programming and performance
requirements. Without a templating system, a single script
containing the application logic and presentation markup is often
authored by both a designer and a developer simultaneously. This is
inefficient, error-prone, and difficult to maintain, as multiple
people with different purposes in mind must change the same file.
To solve this problem, the ACS Templating System, separates the
responsibilities of writing the page into separate application
logic and presentation layers.
<h3>How the Templating System Works</h3><p>This separation is achieved through utilization of the
Model-View-Controller (MVC) pattern. The MVC pattern is a classic
design pattern that identifies clear roles for components in GUI
application with persistent data originally developed for
SmallTalk-80 by Steve Burbeck. The <strong>model</strong>
represents the object, its data, and methods for updating the data.
The <strong>view</strong> provides a user a UI to see and
manipulate the data in the model. The <strong>controller</strong>
provides the system necessary to connect the model and the view to
the user's requests. This <a href="templating.jpg">diagram</a>
summarizes how the process flow of the templating system using the
MVC framework. The filename <strong>dynamic-page</strong> is simply
an example.</p><p>The <strong>model</strong> in the templating system is the
representation in the database of the <a href="/doc/objects">ACS Objects</a> and their associated PL/SQL
package methods. The <strong>view</strong> is the ADP template that
formats the datasources retrieved through the controller into a
presentation for a user. The <strong>controller</strong> is the
combination of the <a href="/doc/request-processor">Request
Processor</a> and the application logic pages implemented as .tcl
scripts that prepare data sources for the templating system.</p><p>This framework permits a clear separation between the logic that
retrieves data from the database and the markup that prepares the
data for display. The designer can focus on presentation and
usability issues and need only write HTML markup. The developer can
focus on the programming necessary to retrieve the data for the
designer and does not need to write HTML markup. These tasks are
separated into separate files so that the two tasks do not
interfere with each other.</p><p>The design of the templating system makes it easier to include
reusable presentation components as <a href="components">included templates</a> and <a href="master">master templates</a>, as explained in "<a href="composite">Composite Page</a>". Moreover, the ACS Core pages
are templated which enables users of the ACS who want to customize
their look and feel to update a site-wide master or the individual
templates without touching the application logic. If a bug is fixed
in the application logic, the application logic script can be
replaced without affecting the template.</p><p>The rest of this document explains the steps necessary to write
a templated page.</p><h3>Choose the data you wish to present</h3><p>The first step in building a dynamic page is to decide, at least
to a first approximation, on the data you wish to present to the
user. For example, a site that allows users to manage their car
maintenance records might want to present the following data on the
user's home page:</p><ul>
<li>The user's name.</li><li>The user's city of residence.</li><li>A list of the user's cars, showing the year, make, and
model.</li><li>A list of messages or alerts related to the user's cars.</li><li>A list of local events or special offers from mechanics or
dealers.</li>
</ul><p>Note that our definition of <em>data</em> encompasses
<em>everything that is unique to a particular user's
experience</em>. It does <em>not</em> include text or other layout
features that will appear the same for all users.</p><p>Each of the items in the above list constitutes a <em>data
source</em> which the system merges with a template to produce the
finished page. The publisher typically describes the data to
present on each page as part of the site specification.</p><h3>Implement the Data Sources</h3><p>Once the publishing team has described the data to present on a
page, the developer writes a Tcl script to <a href="data">implement the data sources</a>. The Tcl script should
be located under the page root at the URL of the finished page. For
example, a dynamic page that will be located at
<tt>http://yoursite.com/cars.acs</tt> requires a Tcl script located
on the server at <tt>/web/yoursite/www/cars.tcl</tt> (or wherever
your pages happen to be located).</p><p>In addition to setting data sources, the Tcl script may perform
any other required tasks, such as checking permissions, performing
database transactions or sending email. It may also redirect to
another URL if necessary. The Tcl script may optionally use logic
to change which page is being delivered, specified by
<code>ad_return_template &lt;filename&gt;</code>. If no filename is
supplied, <code>ad_return_template</code> does nothing. If the page
as defined after the last call to ad_return_template differs from
what it was at the beginning of the page, its datasource
preparation script is run <em>in the same scope</em>, in fact
accumulating datasources. By default the templating system looks
for a file with the same name as the Tcl script, but for the
template with the extension <strong>.adp</strong>.</p><h3>Document the Data Sources</h3><p>The developer should include comments in the Tcl code
documenting each data source. A templating system specifies
recognizes special <a href="document">documentation
directives</a> that allow the comments to be extracted from the
code and accessed by the designer or publisher for reference.</p><h3>Write the Template</h3><p>The final step is to <a href="templates">write a
template</a> specifying the layout of the page. Template files must
have the <tt>adp</tt> extension. By default the system looks for
the template at the same location as the associated Tcl script,
such as <tt>/web/yoursite/www/cars.adp</tt>.</p><p>The layout is mostly HTML, with a small number of additional
custom tags to control the presentation of dynamic data on the
page. In most cases, the initial draft of the template will be
written by the developer in the course of testing the Tcl script.
The designer may then enhance the layout as required.</p><hr><a href="mailto:docs\@openacs.org">docs\@openacs.org</a>
</body>
This diff is collapsed.
This diff is collapsed.
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Presenting Data in Multiple
Styles and Formats}</property>
<property name="doc(title)">Templating System User Guide: Presenting Data in Multiple
Styles and Formats</property>
<master>
<body>
<h2>Presenting Data in Multiple Styles and Formats</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<p>(Discussion of how to do cobranding, syndication of data in XML,
etc.).</p><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
<property name="context">{/doc/acs-templating {Templating}} {Templating System User Guide: Embedding Code in
Templates}</property>
<property name="doc(title)">Templating System User Guide: Embedding Code in
Templates</property>
<master>
<body>
<h2>Embedding Code in Templates</h2><a href="..">Templating System</a> : <a href="../developer-guide.html">Developer Guide</a> : User Guide
<p>There are various ways to use Tcl in ADPs like ASP or JSP.</p><p>You can use the <code>&lt;% ... %&gt;</code> and <code>&lt;%=
... %&gt;</code> tags just as in an ADP page handled by the
AOLserver. For examples, see the section "embedded tcl" on the
<a href="../demo">demonstration page</a>.</p><p>Generally, avoid putting escaped Tcl code in adp files, or
generating HTML fragments in tcl procedures. It subverts the
separation of code and layout, one of the benefits of templating.
Embedded Tcl makes templates non-portable to ACS/Java.</p><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<property name="context">{/doc/acs-templating {Templating}} {Templating System Tag Reference: Master}</property>
<property name="doc(title)">Templating System Tag Reference: Master</property>
<master>
<body>
<h2>Master</h2><a href="..">Templating System</a> : <a href="../designer-guide.html">Designer Guide</a> : <a href="index">Tag Reference</a> : Master
<h3>Summary</h3><p>The <tt>master</tt> tag is used to specify the relative or
absolute URL of another template to serve as a frame for the
current template. The entire contents of the current template are
inserted into the master template at a position designated by the
<a href="slave"><tt>slave</tt></a> tag in the master
template.</p><h3>Usage</h3><pre>
&lt;master src="master"&gt;
&lt;property name="title"&gt;My Home Page&lt;/property&gt;
&lt;p&gt;Welcome to my home page!&lt;/p&gt;
...
</pre><h3>Note(s)</h3><ul><li><p>See <a href="property"><tt>property</tt></a> and <a href="slave"><tt>slave</tt></a> for more information related to
master templates.</p></li></ul><hr><a href="mailto:templating\@arsdigita.com">templating\@arsdigita.com</a>
</body>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment