You can associate any ACS Object with one or more categories. 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 /acs/admin and install it. This step 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 in three steps:
The Categories service provides a mechanism to associate one or more category trees that are relevant to a particular application instance. One example of such tree is a tree of geographical locations. Continents are on the top of such tree, each continent containing countries etc. Another tree might contain market segments etc. Before users of your application can take advantage of the Categories service there needs to be a way for administrators of your application to choose which category trees are applicable for the application.
The way to achieve this is is to provide a link to the Category Management pages. Add the following snippet to your /var/lib/aolserver/service0/packages/myfirstpackage/www/admin/index.tcl file:
set category_map_url [export_vars -base \ "[site_node::get_package_url -package_key categories]cadmin/one-object" \ { { object_id $package_id } }]
and the following snippet to your /var/lib/aolserver/service0/packages/myfirstpackage/www/admin/index.adp file:
<li><a href="@category_map_url@" class="action_link">Site-Wide Categories</a>
The link created by the above code will take the admin to the generic admin UI where he can pick category trees that make sense for this application. The same UI also includes facilities to build and edit category trees. Notice that the only parameter in this example is package_id so that category trees will be associated with the object identified by this package_id. The categorization service is actually more general than that: instead of package_id you could use an ID of some other object that serves as a "container" in your application. For example, if your discussion forums application supports multiple forums you would use forum_id to associate category trees with just that one forum rather than the entire application instance.
Once the category trees have been selected users need a way 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 note-edit.tcl page with added sections emphasized.
ad_page_contract { This is the view-edit page for notes. @author Your Name (you@example.com) @cvs-id $Id: ch10s06.html,v 1.5 2004/03/04 14:09:21 joela Exp $ @param item_id If present, assume we are editing that note. Otherwise, we are creating a new note. } { item_id:integer,optional } ad_form -name note -form { {item_id:key} {title:text {label Title}} } category::ad_form::add_widgets \ -form_name note \ -container_object_id [ad_conn package_id] \ -categorized_object_id [value_if_exists item_id] ad_form -extend -name note \ -new_request { permission::require_permission -object_id [ad_conn package_id] -privilege create set page_title "Add a Note" set context [list $page_title] } -edit_request { permission::require_write_permission -object_id $item_id mfp::note::get \ -item_id $item_id \ -array note_array set title $note_array(title) set page_title "Edit a Note" set context [list $page_title] } -on_submit { set category_ids [category::ad_form::get_categories \ -container_object_id [ad_conn package_id]] } -new_data { mfp::note::add \ -title $title \ -item_id $item_id category::map_object \ -remove_old \ -object_id $item_id \ $category_ids set message "Note $title added" } -edit_data { mfp::note::edit \ -item_id $item_id \ -title $title category::map_object \ -remove_old \ -object_id $item_id \ $category_ids set message "Note $title changed" } -after_submit { ad_returnredirect -message $message "." ad_script_abort }
Note how we have replaced what was a single ad_form invocation with two. The -extend flag is used to build a form incrementally. We had to do it so that we can insert the call to category::ad_form::add_widgets. This procedure will add as many category widgets as there are trees associated with our package_id. The complementary proc category::ad_form::get_categories will take care of collecting the values after the form has been submitted. The block -on_submit will get executed at this time, followed by execution of either -new_data or -edit_data, depending on whether we are adding a new note or editing an existing one.