<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Advanced Topics</title><meta name="generator" content="DocBook XSL Stylesheets V1.62.0"><link rel="home" href="index.html" title="OpenACS Core Documentation"><link rel="up" href="tutorial.html" title="Chapter�7.�Development Tutorial"><link rel="previous" href="tutorial-debug.html" title="Debugging and Automated Testing"><link rel="next" href="dev-guide.html" title="Chapter�8.�Development Reference"><link rel="stylesheet" href="openacs.css" type="text/css"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><a href="http://openacs.org"><img src="/doc/images/alex.jpg" border="0" alt="Alex logo"></a><table width="100%" summary="Navigation header" border="0"><tr><td width="20%" align="left"><a accesskey="p" href="tutorial-debug.html">Prev</a> </td><th width="60%" align="center">Chapter�7.�Development Tutorial</th><td width="20%" align="right"> <a accesskey="n" href="dev-guide.html">Next</a></td></tr></table><hr></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="tutorial-advanced"></a>Advanced Topics</h2></div></div><div></div></div><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Important</h3><p>This section is a work in progress.</p></div><div class="authorblurb"><p>by <a href="mailto:joel@aufrecht.org" target="_top">Joel Aufrecht</a></p>
          OpenACS docs are written by the named authors, and may be edited
          by OpenACS documentation staff.
        </div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2848813"></a>Overview</h3></div></div><div></div></div><p>This tutorial covers topics which are not essential to
    creating a minimal working package.  Each section can be used
    independently of all of the others; all sections assume that
    you've completed the basic tutorial.</p><div class="itemizedlist"><ul type="disc"><li><p>How to enforce security so that users can't
      change other users records</p></li><li><p>How to use the content management tables so that
      ... what?</p></li><li><p>How to change the default stylesheets for Form
      Builder HTML forms.</p></li><li><p>How to make your package searchable with OpenFTS/Oracle</p></li><li><p>How to make your package send email notifications</p></li><li><p>How to prepare pagelets for inclusion in other pages</p></li><li><p>How and when to put procedures in a tcl procedure library</p></li><li><p>How to add general_comments to your pages</p></li><li><p>More on ad_form - data validation, other stuff.
      (plan to draw from Jon Griffin's doc)</p></li><li><p>How and when to implement caching</p></li><li><p>partialquery in xql</p></li><li><p>How to use the html/text entry widget to get the
      "does this look right" confirm page </p></li><li><p>APM package dependencies</p></li></ul></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2848917"></a>Write the Requirements and Design Specs</h3></div></div><div></div></div><p>It's time to document.  For the tutorial we'll use
      pre-written documentation.  When creating a package
      from scratch, start by copying the documentation template from
	<tt class="computeroutput">/var/lib/aolserver/openacs-dev/packages/acs-core-docs/xml/docs/xml/package-documentation-template.xml</tt>
	to
	<tt class="computeroutput">yourpackage/www/docs/xml/index.xml</tt>.</p><p>You then edit that file with emacs to write the 
	requirements and design sections, generate the html, and start
	coding.  Store any supporting files, like page maps or schema
      diagrams, in the <tt class="computeroutput">www/doc/xml</tt>
      directory, and store png or jpg versions of supporting files in the
	<tt class="computeroutput">www/doc</tt> directory.</p><p>For this tutorial, you should instead install the
	pre-written documentation files for the tutorial app.  Log in
      as <span class="replaceable"><span class="replaceable">service0</span></span>, create the standard
      directories, and copy the prepared documentation:</p><pre class="screen">[service0@yourserver service0]$ <b class="userinput"><tt>cd /var/lib/aolserver/service0/packages/samplenote/</tt></b>
[service0@yourserver samplenote]$ <b class="userinput"><tt>mkdir -p www/doc/xml</tt></b>
[service0@yourserver samplenote]$ <b class="userinput"><tt>cd www/doc/xml</tt></b>
[service0@yourserver xml]$ <b class="userinput"><tt>cp /var/lib/aolserver/service0/packages/acs-core-docs/www/files/samplenote/* .</tt></b>
[service0@yourserver xml]$</pre><p> OpenACS uses DocBook for documentation.  DocBook is
	an XML standard for semantic markup of documentation.  That
	means that the tags you use indicate meaning, not intended
	appearance.  The style sheet will determine appearance.  You
      will edit the text in an xml file, and then process the file
      into html for reading.</p><p>Open the file <tt class="computeroutput">index.xml</tt>
      in emacs.  Examine the file.  Find the version history (look for the tag
        <tt class="computeroutput">&lt;revhistory&gt;</tt>).  Add a
        new record to the document version history.  Look for the
        <tt class="computeroutput">&lt;authorgroup&gt;</tt> tag and
        add yourself as a second author.  Save and exit.  For tips on
        editing SGML files in emacs, see <a href="docbook-primer.html">OpenACS Documentation Guide</a></p><p>Process the xml file to create html documentation.  The
      html documentation, including supporting files such as pictures,
      is stored in the <tt class="computeroutput">www/docs/</tt>
      directory.  A Makefile is provided to generate html from the xml, and copy all of the
      supporting files.  If Docbook is set up correctly, all you need
      to do is:</p><pre class="screen">[service0@yourserver xml]$<b class="userinput"><tt> make</tt></b>
cd .. ; /usr/bin/xsltproc ../../../acs-core-docs/www/xml/openacs.xsl xml/index.xml
Writing requirements-introduction.html for sect1(requirements-introduction)
Writing requirements-overview.html for sect1(requirements-overview)
Writing requirements-cases.html for sect1(requirements-cases)
Writing sample-data.html for sect1(sample-data)
Writing requirements.html for chapter(requirements)
Writing design-data-model.html for sect1(design-data-model)
Writing design-ui.html for sect1(design-ui)
Writing design-config.html for sect1(design-config)
Writing design-future.html for sect1(design-future)
Writing filename.html for chapter(filename)
Writing user-guide.html for chapter(user-guide)
Writing admin-guide.html for chapter(admin-guide)
Writing bi01.html for bibliography
Writing index.html for book
[service0@yourserver xml]$</pre><p>Verify that the documentation was generated and reflects
      your changes by browsing to <tt class="computeroutput">http://<span class="replaceable"><span class="replaceable">yoursite</span></span>:8000/samplenote/doc</tt></p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2887176"></a>Add the new package to CVS</h3></div></div><div></div></div><p>Before you do any more work, make sure that your work is
      protected by putting it all into cvs.  The <tt class="computeroutput">cvs
      add</tt> command is not recursive, so you'll have to
      traverse the directory tree manually and add as you go.  (<a href="http://www.piskorski.com/docs/cvs-conventions.html" target="_top">More on
      CVS</a>)</p><pre class="screen">[service0@yourserver xml]$ <b class="userinput"><tt>cd ..</tt></b>
[service0@yourserver doc]$ <b class="userinput"><tt>cd ..</tt></b>
[service0@yourserver www]$ <b class="userinput"><tt>cd ..</tt></b>
[service0@yourserver samplenote]$ <b class="userinput"><tt>cd ..</tt></b>
[service0@yourserver packages]$ <b class="userinput"><tt>cvs add samplenote/</tt></b>
Directory /cvsroot/service0/packages/samplenote added to the repository
[service0@yourserver packages]$ <b class="userinput"><tt>cd samplenote/</tt></b>
[service0@yourserver samplenote]$ <b class="userinput"><tt>cvs add www</tt></b>
Directory /cvsroot/service0/packages/samplenote/www added to the repository
[service0@yourserver samplenote]$ <b class="userinput"><tt>cd www</tt></b>
[service0@yourserver www]$ <b class="userinput"><tt>cvs add doc</tt></b>
Directory /cvsroot/service0/packages/samplenote/www/doc added to the repository
[service0@yourserver www]$ <b class="userinput"><tt>cd doc</tt></b>
[service0@yourserver doc]$ <b class="userinput"><tt>cvs add *</tt></b>
cvs add: cannot add special file `CVS'; skipping
cvs add: scheduling file `admin-guide.html' for addition
cvs add: scheduling file `bi01.html' for addition
cvs add: scheduling file `data-model.dia' for addition
cvs add: scheduling file `data-model.png' for addition
cvs add: scheduling file `design-config.html' for addition
cvs add: scheduling file `design-data-model.html' for addition
cvs add: scheduling file `design-future.html' for addition
cvs add: scheduling file `design-ui.html' for addition
cvs add: scheduling file `filename.html' for addition
cvs add: scheduling file `index.html' for addition
cvs add: scheduling file `page-map.dia' for addition
cvs add: scheduling file `page-map.png' for addition
cvs add: scheduling file `requirements-cases.html' for addition
cvs add: scheduling file `requirements-introduction.html' for addition
cvs add: scheduling file `requirements-overview.html' for addition
cvs add: scheduling file `requirements.html' for addition
cvs add: scheduling file `sample-data.html' for addition
cvs add: scheduling file `sample.png' for addition
cvs add: scheduling file `user-guide.html' for addition
cvs add: scheduling file `user-interface.dia' for addition
cvs add: scheduling file `user-interface.png' for addition
Directory /cvsroot/service0/packages/samplenote/www/doc/xml added to the repository
cvs add: use 'cvs commit' to add these files permanently
[service0@yourserver doc]$ <b class="userinput"><tt>cd xml</tt></b>
[service0@yourserver xml]$ <b class="userinput"><tt>cvs add Makefile index.xml</tt></b>
cvs add: scheduling file `Makefile' for addition
cvs add: scheduling file `index.xml' for addition
cvs add: use 'cvs commit' to add these files permanently
[service0@yourserver xml]$<b class="userinput"><tt> cd ../../..</tt></b>
[service0@yourserver samplenote]$ <b class="userinput"><tt>cvs commit -m "new package"</tt></b>
cvs commit: Examining .
cvs commit: Examining www
cvs commit: Examining www/doc
cvs commit: Examining www/doc/xml
RCS file: /cvsroot/service0/packages/samplenote/www/doc/admin-guide.html,v
done
Checking in www/doc/admin-guide.html;
/cvsroot/service0/packages/samplenote/www/doc/admin-guide.html,v  &lt;--  admin-guide.html
initial revision: 1.1
done
<span class="emphasis"><em>(many lines omitted)</em></span>
[service0@yourserver samplenote]$</pre></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2887325"></a>Delete with confirmation</h3></div></div><div></div></div><p>We need a way to delete records.  We'll create a
    recursive confirmation page.</p><p>Add this column to the table_def in index.tcl</p><pre class="programlisting">{delete "" {} {&lt;td&gt;&lt;a href="note-delete?note_id=$note_id"&gt;Delete&lt;/a&gt;&lt;/td&gt;}}</pre><p>Create the delete confirmation/execution page.</p><pre class="screen">[service0@yourserver www]$ <b class="userinput"><tt>emacs note-delete.tcl</tt></b></pre><pre class="programlisting">ad_page_contract {
    A page that gets confirmation and then delete notes.

    @author joel@aufrecht.org
    @creation-date 2003-02-12
    @cvs-id $Id: tutorial-advanced.html,v 1.14.2.3 2003/12/08 15:41:19 jeffd Exp $
} {
    note_id:integer
    confirm_p:optional
}

set title "Delete Note"

if {![exists_and_not_null confirm_p]} {
    # first pass, not confirmed.  Display a form for confirmation
    set note_name [db_string get_name { *SQL }]
    set title "Delete $note_name"
    template::form::create note-del-confirm
    template::element::create note-del-confirm note_id -value $note_id -widget hidden
    template::element::create note-del-confirm confirm_p -value 1 -widget hidden
    template::element::create note-del-confirm submit \
      -label "Confirm deletion of $note_name" \
      -widget submit
} else {
    # second pass, confirmed.  Call the database to delete the record
    db_1row do_delete { *SQL* }
    ad_returnredirect "index"
    ad_script_abort
}</pre><p>This page requires a
<tt class="computeroutput">note_id</tt> to determine which record
should be deleted.  It also looks for a confirmation variable, which
should initially be absert.  If it is absent, we create a form to
allow the user to confirm the deletion.  Note that in
<tt class="computeroutput">entry-edit.tcl</tt> we used <tt class="computeroutput">ad_form</tt> to access the Form Template
commands; here, we call them directly because we don't need the extra
features of ad_form.  The form calls itself, but
with hidden variables carrying both
<tt class="computeroutput">note_id</tt> and
<tt class="computeroutput">confirm_p</tt>.  If confirm_p is present,
we delete the record, set redirection back to the index, and abort
script execution.</p><p>The database commands:</p><pre class="screen">[service0@yourserver www]$ <b class="userinput"><tt>emacs note-delete.xql</tt></b></pre><pre class="programlisting">&lt;?xml version="1.0"?&gt;
&lt;queryset&gt;
  &lt;fullquery name="do_delete"&gt;
    &lt;querytext&gt;
      select samplenote__delete(:note_id)
    &lt;/querytext&gt;
  &lt;/fullquery&gt;
  &lt;fullquery name="get_name"&gt;
    &lt;querytext&gt;
      select samplenote__name(:note_id)
    &lt;/querytext&gt;
  &lt;/fullquery&gt;
&lt;/queryset&gt;</pre><p>And the adp page:</p><pre class="screen">[service0@yourserver www]$ <b class="userinput"><tt>emacs note-delete.adp</tt></b></pre><pre class="programlisting">&lt;master&gt;
&lt;property name="title"&gt;@title@&lt;/property&gt;
&lt;property name="context"&gt;{@title@}&lt;/property&gt;
&lt;h2&gt;@title@&lt;/h2&gt;
&lt;formtemplate id="note-del-confirm"&gt;&lt;/formtemplate&gt;
&lt;/form&gt;</pre><p>The ADP is very simple.  The
<tt class="computeroutput">formtemplate</tt> tag outputs the HTML
form generated by the ad_form command with the matching name.  Test it by adding the new files in the APM and then deleting a few samplenotes.</p></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2867937"></a>General_comments</h3></div></div><div></div></div><p>You can track comments for any ACS Object.  Here we'll track
    comments for notes.  On the notes.tcl/adp pair, which is used to
    display individual notes, we want to put a link to add comments at
    the bottom of the screen.  If there are any comments, we want to
    show them.</p><p>First, we need to generate a url for adding comments.  In notes.tcl:</p><pre class="programlisting">
set comment_add_url "[general_comments_package_url]comment-add?[export_vars {
 { object_id $note_id } 
 { object_name $title } 
 { return_url "[ad_conn url]?[ad_conn query]"} 
}]"
</pre><p>This calls a global, public tcl function that the
    general_comments package registered, to get its url. You then
    embed in that url the id of the note and its title, and set the
    return_url to the current url so that the user can return after
    adding a comment.</p><p>We need to create html that shows any existing comments.
    We do this with another general_comments function:</p><pre class="programlisting">set comments_html [general_comments_get_comments
    -print_content_p 1 $note_id]</pre><p>First, we pass in an optional parameter that that says to actually
    show the contents of the comments, instead of just the fact that
    there are comments. Then you pass the note id, which is also the
    acs_object id.</p><p>We put our two new variables in the notes.adp
    page.</p><pre class="programlisting">&lt;a href="@comment_add_url@"&gt;Add a comment&lt;/a&gt;
@comments_html@</pre></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2868008"></a>Prepare the package for distribution.</h3></div></div><div></div></div><p>Browse to the package manager.  Click on
        <tt class="computeroutput"><span class="guilabel"><span class="guilabel">tutorialapp</span></span></tt>.</p><p>Click on <tt class="computeroutput"><span class="guilabel"><span class="guilabel">Generate a distribution file
        for this package from the
        filesystem</span></span></tt>.
</p><p>Click on the file size
        (<tt class="computeroutput"><span class="guilabel"><span class="guilabel">37.1KB</span></span></tt>)
        after the label <tt class="computeroutput"><span class="guilabel"><span class="guilabel">Distribution
        File:</span></span></tt> and save the file to
        /tmp.</p><p><a class="indexterm" name="id2868056"></a>
</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="tutorial-debug.html">Prev</a> </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right"> <a accesskey="n" href="dev-guide.html">Next</a></td></tr><tr><td width="40%" align="left">Debugging and Automated Testing </td><td width="20%" align="center"><a accesskey="u" href="tutorial.html">Up</a></td><td width="40%" align="right"> Chapter�8.�Development Reference</td></tr></table><hr><address><a href="mailto:docs@openacs.org">docs@openacs.org</a></address></div><a name="comments"></a><center><a href="http://openacs.org/doc/tutorial-advanced.html#comments">View comments on this page at openacs.org</a></center></body></html>