Forum OpenACS Q&A: Instructions on how to add categories to your package
Posted by
Nima Mazloumi
on 08/11/04 02:06 PM
Hi all,
below the steps to add categories to a package. Special thanks to Timo, Lars, Dirk, Malte for code and support.
For more info take a look on Documentation on HEAD.
- Make Categories optional for your package.
Goto your package under APM and define the number parameterUseCategoriesP
with default0
- Edit the page where you need to extend your
ad_form
to support categoriesset use_categories_p [parameter::get -parameter "EnableCategoriesP" -default 0] set package_id [ad_conn package_id]
Close thead_form
definition after the switch-form
and put the rest of yourad_form
definition in aif-else
clause.
Note: In the followingentry_id
is the categorized object_id you want support categories and the categories is enabled on package instance level (package_id
). The form name ismy_form
# customize form depending on category capabilities if { $use_categories_p == 1 } { #create link to site-wide categories set category_map_url [export_vars -base "[site_node::get_package_url -package_key categories]cadmin/one-object" { { object_id $package_id } }] #extend the form to support categories category::ad_form::add_widgets -form_name new_quest_answ -container_object_id $package_id -categorized_object_id [value_if_exists entry_id] ad_form -extend -name my_form -select_query_name my_query -on_submit { set category_ids [category::ad_form::get_categories -container_object_id $package_id] } -new_data { #HERE COMES YOU DML CODE category::map_object -remove_old -object_id $entry_id $category_ids db_dml insert_asc_named_object "insert into acs_named_objects (object_id, object_name, package_id) values ( :entry_id, 'FAQ', :package_id)" } } -edit_data { #HERE COMES YOU DML CODE db_dml insert_asc_named_object "update acs_named_objects set object_name = 'FAQ', package_id = :package_id where object_id = :entry_id" category::map_object -remove_old -object_id $entry_id $category_ids } -after_submit { ad_returnredirect "somewhere" ad_script_abort } } else { # HERE COMES YOU OLD FORM DEFINITION }
- In the corresponding adp-file enter this
<if @use_categories_p@> <a href=&34;@category_map_url@&34; >Site-Wide Categories </if>
- If you want to allow the user to switch between categories enabled and disabled do this
- Add the following to your admin tcl page
set use_categories_p [parameter::get -parameter "EnableCategoriesP"] set category_map_url [export_vars -base &34;[site_node::get_package_url -package_key categories]cadmin/one-object&34; { { object_id $package_id } }] set return_url [ns_conn url]
- And this in the adp file
<a href=toggle-cat-mode?<&37;=[export_url_vars return_url]&37;>>Configure categories mode <if @use_categories_p@> <a href=&34;@category_map_url@&34; >Site-Wide Categories </if>
- Create the
toggle-cat-mode
-Pagead_page_contract { This page allows a faq admin to change the categories usage mode. @author Nima Mazloumi (nima.mazloumi@gmx.de) @creation-date 2004-08-11 } { {return_url ""} } set title "Configure category mode" set context [list $title] set use_categories_p [parameter::get -parameter "EnableCategoriesP"] ad_form -name categories_mode -form { {enabled_p:text(radio) {label "Enable Categories"} {options {{Yes 1} {No 0}}} {value $use_categories_p} } {return_url:text(hidden) {value $return_url}} {submit:text(submit) {label "Set Mode"}} } -on_submit { parameter::set_value -parameter "EnableCategoriesP" -value $enabled_p if {![empty_string_p $return_url]} { ns_returnredirect $return_url } }
- And this in the corresponding adp
<master> <property name="title">@title@</property> <property name="context">@context@</property> <formtemplate id="categories_mode"></formtemplate>
- Add the following to your admin tcl page
- Now we will enable category filters for your view page. I assume that this page is called
view
- Add this parameter to the
view.tcl
,ad_page_contract { YOUR TEXT } { YOURPARAMS {category_id:integer,optional {}} }
- Change your sql-query depending on whether categories is enabled or not
# Use Categories? set use_categories_p [parameter::get -parameter "EnableCategoriesP" -default 0] if { $use_categories_p == 1 && [exists_and_not_null category_id] } { # Add to your from clause 'category_object_map com, acs_named_objects nam' # Add to your where clause 'com.object_id = qa.entry_id and # nam.package_id = :package_id and # com.object_id = nam.object_id and # com.category_id = :category_id' set select_sql_query "YOUR NEW QUERY" } else { set select_sql_query "YOUR ORIGINAL QUERY" }
- Append this at the end of
view.tcl
# Site-Wide Categories if { $use_categories_p == 1} { set package_url [ad_conn package_url] if { ![empty_string_p $category_id] } { set category_name [category::get_name $category_id] if { [empty_string_p $category_name] } { ad_return_exception_page 404 "No such category" "Site-wide \ Category with ID $category_id doesn't exist" return } # Show Category in context bar append context_base_url /cat/$category_id lappend context [list $context_base_url $category_name] set type "all" } # Cut the URL off the last item in the context bar if { [llength $context] > 0 } { set context [lreplace $context end end [lindex [lindex $context end] end]] } db_multirow -unclobber -extend { category_name tree_name } categories categories { select c.category_id as category_id, c.tree_id from categories c, category_tree_map ctm where ctm.tree_id = c.tree_id and ctm.object_id = :package_id } { set category_name [category::get_name $category_id] set tree_name [category_tree::get_name $tree_id] } }
- And now change
view.adp
. Note that you need to adjust the queries to forward those parameters you need to display your items correctlyYOURPARAMS
. Also changeYOURPACKAGE
to your your correct package name.<if @use_categories_p@> <multiple name="categories"> <h2>@categories.tree_name@ <group column="tree_id"> <a href="@package_url@cat/@categories.category_id@?@YOURPARAMS@&category_id=@categories.category_id@">@categories.category_name@
</group> </multiple>
<a href=&34;@package_url@view?@YOURPARAMS@&34;>All Items </if> - Finally add a
index.vuh
file to the root of your packagewww
folderset url /[ad_conn extra_url] if {[regexp {^/+cat/+([^/]+)/*} $url \ ignore_whole sw_category_id]} { # SWC (Site-wide categories) # As the categories package currently doesn't have short names we # are using IDs. We don't check whether this is a valid integer here # because index.tcl will take care of that. rp_form_put sw_category_id $sw_category_id } rp_internal_redirect "/packages/YOURPACKAGE/www/view"
- Add this parameter to the
- Finally make sure to delete the entries in
acs_named_object
when your items are deleted.db_dml delete_named_object "delete from acs_named_objects where object_id = :entry_id"
Greetings
Nima
Posted by
Jade Rubick
on 08/11/04 05:30 PM
Nima, could you add this to the documentation for categories? You could even just take the HTML you posted, and put it in a tutorial page or something.
Posted by
Nima Mazloumi
on 08/13/04 12:24 PM
Added this to documentation on HEAD. Hope I didn't make any mistake :)