Index: openacs-4/packages/acs-core-docs/www/xml/developers-guide/tutorial-advanced.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/xml/developers-guide/tutorial-advanced.xml,v diff -u -N -r1.52 -r1.53 --- openacs-4/packages/acs-core-docs/www/xml/developers-guide/tutorial-advanced.xml 27 Jun 2015 17:19:13 -0000 1.52 +++ openacs-4/packages/acs-core-docs/www/xml/developers-guide/tutorial-advanced.xml 7 Aug 2017 23:47:54 -0000 1.53 @@ -12,14 +12,14 @@ 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. + you've completed the basic tutorial. Write the Requirements and Design Specs Before you get started you should make yourself familiar with the tags that are used to write your documentation. For tips on editing SGML files in emacs, see . - It's time to document. For the tutorial we'll use + 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 /var/lib/aolserver/openacs-dev/packages/acs-core-docs/xml/docs/xml/package-documentation-template.xml @@ -82,7 +82,7 @@ Add the new package to CVS Before you do any more work, make sure that your work is protected by putting it all into cvs. The cvs - add command is not recursive, so you'll have to + add command is not recursive, so you'll have to traverse the directory tree manually and add as you go. (More on CVS) @@ -181,7 +181,7 @@ In this problem set you will familiarise yourself with the templating system in openacs. This will be achieved through customising an existing edit-this-page application template. - Before proceeding, it is strongly advised to read the templating documentation on your openacs installation (http://localhost:8000/doc/acs-templating). The documentation lists the special tags available for ADP files. + Before proceeding, it is strongly advised to read the templating documentation on your OpenACS installation (http://localhost:8000/doc/acs-templating). The documentation lists the special tags available for ADP files. @@ -327,7 +327,7 @@ Who Wrote This and When - This problem set was originally written by Nick Carroll in August 2004 for the University of Sydney Course EBUS5002. + This problem set was originally written by Nick Carroll in August 2004 for the University of Sydney Course EBUS5002. This material is copyright 2004 by Nick Carroll. It may be copied, reused, and modified, provided credit is given to the original author. ($Id$) @@ -336,7 +336,7 @@ Adding Comments - You can track comments for any ACS Object. Here we'll track + You can track comments for any ACS Object. Here we'll track comments for notes. On the note-edit.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 @@ -349,7 +349,7 @@ { return_url "[ad_conn url]?[ad_conn query]"} }] - This calls a global, public tcl function that the + 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 @@ -380,7 +380,7 @@ Delete Selected button on the bottom of the list. Dedicated admin pages. If you want admins to have - access to data that users aren't interested in or aren't allowed + access to data that users aren't interested in or aren't allowed to see you will need dedicated admin pages. The conventional place to put those dedicated admin pages is in the /var/lib/aolserver/$OPENACS_SERVICE_NAME/packages/myfirstpackage/www/admin @@ -389,7 +389,7 @@ [$OPENACS_SERVICE_NAME www]$ mkdir admin [$OPENACS_SERVICE_NAME www]$ cd admin - Even if your application doesn't need any admin pages of its own you will + Even if your application doesn't need any admin pages of its own you will usually need at least one simple page with a bunch of links to existing administration UI such as Category Management or standard Parameters UI. Adding the link to Category Management is described in the section on @@ -431,12 +431,12 @@ Now that you have the first admin page it would be nice to have a link to it -somewhere in the system so that admins don't have to type in the +somewhere in the system so that admins don't have to type in the /admin every time they need to reach it. You could put a static link to the toplevel index.adp but that might be distracting for people who are not admins. Besides, some people consider it impolite to first -offer a link and then display a nasty "You don't have permission to access this +offer a link and then display a nasty "You don't have permission to access this page" message. @@ -477,20 +477,20 @@ extended by Nima Mazloumi You can associate any ACS Object with one or more categories. - In this tutorial we'll show how to equip your application with user + In this tutorial we'll show how to equip your application with user interface to take advantage of the Categories service. - We'll start by installing the Categories service. Go to + We'll start by installing the Categories service. Go to /acs/admin and install it. This step - won't be necessary for the users of your applications because you'll create + won't be necessary for the users of your applications because you'll create a dependency with the Package Manager which will take care that the Categories service always gets installed when your application gets installed. Now that we have installed the Categories service we can proceed to - modifying our application so that it can take advantage of it. We'll do it + modifying our application so that it can take advantage of it. We'll do it in three steps: @@ -520,7 +520,7 @@ file: - <a href="@category_map_url@"<#categories.Site_wide_Categories#</a> + <a href="@category_map_url@">#­categories.Site_wide_Categories#</a> The link created by the above code (category_map_url) will take the admin to the generic @@ -543,12 +543,12 @@ to categorize items. The easiest way to do this is by adding the category widget type of the form builder to note-edit.tcl. - To achieve this we'll need to use the -extend - switch to the ad_form command. Here's the "meat" of the + To achieve this we'll need to use the -extend + switch to the ad_form command. Here's the "meat" of the note-edit.tcl page: - #extend the form to support categories - set package_id [ad_conn package_id] + # extend the form to support categories + set package_id [ad_conn package_id] category::ad_form::add_widgets -form_name note -container_object_id $package_id -categorized_object_id [value_if_exists item_id] @@ -583,7 +583,7 @@ should initially be absert. If it is absent, we create a form to allow the user to confirm the deletion. Note that in entry-edit.tcl we used ad_form to access the Form Template -commands; here, we call them directly because we don't need the extra +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 note_id and @@ -608,7 +608,8 @@ </queryset> And the adp page: [$OPENACS_SERVICE_NAME@yourserver www]$ emacs note-delete.adp - <master> + +<master> <property name="title">@title@</property> <property name="context">{@title@}</property> <h2>@title@</h2> @@ -635,7 +636,7 @@ <a href=configure?<%=[export_vars -url {return_url}]%>>Configure</a> <if @use_categories_p@> - <a href="@category_map_url@"<#categories.Site_wide_Categories#</a> + <a href="@category_map_url@">#­categories.Site_wide_Categories#</a> </if> Now create a configure page @@ -743,7 +744,7 @@ set category_name [category::get_name $category_id] if { $category_name eq "" } { ad_return_exception_page 404 "No such category" "Site-wide \ - Category with ID $category_id doesn't exist" + Category with ID $category_id doesn't exist" return } # Show Category in context bar @@ -782,13 +783,12 @@ Finally you need a an index.vuh in your www folder to rewrite the URLs correctly, : - set url /[ad_conn extra_url] + set url /[ad_conn extra_url] - if {[regexp {^/+cat/+([^/]+)/*} $url \ - ignore_whole category_id]} { - rp_form_put category_id $category_id - } - rp_internal_redirect "/packages/YOURPACKAGE/www/index" + if {[regexp {^/+cat/+([^/]+)/*} $url ignore_whole category_id]} { + rp_form_put category_id $category_id + } + rp_internal_redirect "/packages/YOURPACKAGE/www/index" Now when ever the user select a category only notes that belong to this category are displayed. @@ -846,10 +846,10 @@ developer, there are a couple of steps you need to take in order to release a new version of your package. - For the sake of this example, let's assume you are the + For the sake of this example, let's assume you are the package owner of the notes package. It is currently at version 1.5, and you are planning on - releasing version 1.6. It is also located in OpenACS's CVS. + releasing version 1.6. It is also located in OpenACS's CVS. To release your package: cd /path/to/notes @@ -870,7 +870,7 @@ The notifications package allows you to send notifications through any - defined communications medium (e.g. email, sms) upon some event occuring within + defined communications medium (e.g. email, sms) upon some event occurring within the system. This tutorial steps through the process of integrating the notifications package with your package. @@ -954,7 +954,7 @@ -- @creation-date 2002-05-16 -- -- This code is newly concocted by Ben, but with significant concepts and code - -- lifted from Gilbert's UBB forums. Thanks Orchard Labs. + -- lifted from Gilbert's UBB forums. Thanks Orchard Labs. -- Lars and Jade in turn lifted this from gwong and ben. create function inline_0 () @@ -1054,7 +1054,7 @@ -notif_text $new_content - This code is placed in the tcl procedure that creates blog + This code is placed in the Tcl procedure that creates blog entries, right after the entry gets created in the code. The $blog(package_id) is the OpenACS object_id of the Weblogger instance to which the entry has been @@ -1138,7 +1138,7 @@ tree_level() function, which gives you the level, starting from 1, 2, 3... - Here's an example, pulling all of the children for a given + Here's an example, pulling all of the children for a given parent: @@ -1155,14 +1155,14 @@ and parent.key = :the_parent_key; - The reason we substract the parent's tree_level from the - child's tree_level is that the tree_levels are global, so if you - want the parent's tree_level to start with 0, you'll want the - subtraction in there. This is a reason you'll commonly see magic + The reason we subtract the parent's tree_level from the + child's tree_level is that the tree_levels are global, so if you + want the parent's tree_level to start with 0, you'll want the + subtraction in there. This is a reason you'll commonly see magic numbers in tree_sortkey SQL queries, like tree_level(children.tree_sortkey) - 4. That is basically an incorrect way to do it, - and subtracting the parent's tree_level is the preferred method. + and subtracting the parent's tree_level is the preferred method. This example does not include the parent. To return the entire subtree including the parent, leave out the non-equals clause: @@ -1257,14 +1257,14 @@ <table border="0" width="100%"> <tr> <td valign="top" width="50%"> - <table class="element" border=0 cellpadding="0" cellspacing="0" width="100%"> + <table class="element" border="0" cellpadding="0" cellspacing="0" width="100%"> <tr> - <td colspan=3 class="element-header-text"> + <td colspan="3" class="element-header-text"> <bold>Groups</bold> </td> </tr> <tr> - <td colspan=3 class="dark-line" height="0"><img src="/resources/acs-subsite/spacer.gif"></td></tr> + <td colspan="3" class="dark-line" height="0"><img src="/resources/acs-subsite/spacer.gif"></td></tr> <tr> <td class="light-line" width="1"> <img src="/resources/acs-subsite/spacer.gif" width="1"> @@ -1367,7 +1367,7 @@ } - In your code, always call my_proc. There will be a seperate cache item for each unique call to my_proc_not_cached so that calls with different arguments are cached seperately. You can flush the cache for each cache key by calling util_memoize_flush my_proc_not_cached args. + In your code, always call my_proc. There will be a separate cache item for each unique call to my_proc_not_cached so that calls with different arguments are cached separately. You can flush the cache for each cache key by calling util_memoize_flush my_proc_not_cached args. @@ -1384,7 +1384,7 @@ - If you are correctly flushing the cached value, then it will need to be reloaded. You may wish to pre-load it, so that the loading delay does not impact users. If you have a sequence of pages, you could call the cached proc in advance, to increase the chances that it's loaded and current when the user reaches it. Or, you can call (and discard) it immediately after flushing it. + If you are correctly flushing the cached value, then it will need to be reloaded. You may wish to pre-load it, so that the loading delay does not impact users. If you have a sequence of pages, you could call the cached proc in advance, to increase the chances that it's loaded and current when the user reaches it. Or, you can call (and discard) it immediately after flushing it. @@ -1434,7 +1434,7 @@ } ... - You must not give your your form the same name that your page has. Otherwise HTMLArea won't load. + You must not give your your form the same name that your page has. Otherwise HTMLArea won't load. Convert your textarea widget to a richtext widget and enable htmlarea. The htmlarea_p-flag can be used to prevent @@ -1455,7 +1455,7 @@ ad_form or you will have problems displaying the content or handling the data manipulation correctly. Depending on the data model of your package you either support a content format - or don't. If you don't you can assume "text/html" or + or don't. If you don't you can assume "text/html" or "text/richtext" or "text/enhanced". The relevant parts in your ad_form definition are the switches -new_data, -edit_data, @@ -1474,7 +1474,7 @@ Now the correct values for my_input_field_2 and format are passed to the -new_data and - -edit_data blocks which don't need to get touched. + -edit_data blocks which don't need to get touched. To make HTMLArea optional per package instance define a string parameter UseWysiwygP which defaults 0 for your package using the APM. @@ -1494,34 +1494,34 @@ All you need now is a configuration page where the user can change this setting. Create a configure.tcl file: - ad_page_contract { +ad_page_contract { - This page allows a faq admin to change the UseWysiwygP setting + This page allows a faq admin to change the UseWysiwygP setting - } { - {return_url ""} - } +} { + {return_url ""} +} - set title "Should we support WYSIWYG?" - set context [list $title] + set title "Should we support WYSIWYG?" + set context [list $title] - set use_wysiwyg_p + set use_wysiwyg_p - ad_form -name categories_mode -form { - {enabled_p:text(radio) - {label "Enable WYSIWYG"} - {options {{Yes t} {No f}}} - {value $use_wysiwyg_p} - } - {return_url:text(hidden) {value $return_url}} - {submit:text(submit) {label "Change"}} - } -on_submit { - parameter::set_value -parameter "UseWysiwygP" -value $enabled_p - if {$return_url ne ""} { - ns_returnredirect $return_url - } - } - + ad_form -name categories_mode -form { + {enabled_p:text(radio) + {label "Enable WYSIWYG"} + {options {{Yes t} {No f}}} + {value $use_wysiwyg_p} + } + {return_url:text(hidden) {value $return_url}} + {submit:text(submit) {label "Change"}} + } -on_submit { + parameter::set_value -parameter "UseWysiwygP" -value $enabled_p + if {$return_url ne ""} { + ns_returnredirect $return_url + } + } + In the corresponding ADP file write <master> @@ -1555,7 +1555,7 @@ Under the Manage section, click on Parameters - It's fairly self-explanatory at this point. Create the + It's fairly self-explanatory at this point. Create the parameters you want, and then access them in your code using the parameter::get procedure. @@ -1596,7 +1596,7 @@ legacy. - Modify config.tcl to accomodate the legacy database, and to + Modify config.tcl to accommodate the legacy database, and to ensure that the legacy database is not used for standard OpenACS queries: ns_section ns/db/pools @@ -1659,7 +1659,7 @@ db_ API calls. For example, suppose there is a table called "foo" in the legacy system, with a field "bar". List "bar" for all records with - this tcl file: + this Tcl file: db_foreach -dbn legacy get_bar_query { select bar from foo limit 10 @@ -1674,7 +1674,7 @@ Future Topics - How to enforce security so that users can't + How to enforce security so that users can't change other users records How to use the content management tables so that @@ -1683,9 +1683,9 @@ Builder HTML forms. How to make your package searchable with OpenFTS/Oracle How to prepare pagelets for inclusion in other pages - How and when to put procedures in a tcl procedure library + How and when to put procedures in a Tcl procedure library More on ad_form - data validation, other stuff. - (plan to draw from Jon Griffin's doc) + (plan to draw from Jon Griffin's doc) partialquery in xql How to use the html/text entry widget to get the "does this look right" confirm page