ACS Modules

part of the ArsDigita Community System by Tarik Alatovic

The Big Picture

An ACS module is a self-contained subsystem delivering a service visible to the end-user. From programmers point of view, it is a collection of sql tables definitions supported by an html interface generated by a scripting language such as tcl. In order for a module to become a part of Arsdigita toolkit, it must implement common and reusable functionality. Examples of modules in Arsdigita toolkit are News, Bulletin Board, Address Book and Ecommerce modules.

Module Architecture

Directory Structure Let's take faq module (Frequently Asked Questions) as an example. It's files are stored in 3 directories: /faq, /faq/admin and /admin/faq. We need these three separate directories in order to separate three levels of access to the module data: public, module administration and system administration. Pages in /faq are public pages showing faq questions and answers to the users. Pages in /faq/admin are pages where module admistrator can add, edit or remove faq questions and answers. Pages in /admin/faq are provided for system administrator who may need to add or delete whole faqs, collect faq module statistics (e.g, how many people used faq module in the previous month) and be able to do other operations refering to the whole faq module and not just to an instance of it. Data Model Data model for the module should reside in /doc/sql directory (e.g. /doc/sql/faq.sql for faq module). Data modeling is the hardest and most important part of any module. If you get the data model wrong, your module might not do what users need, it might be unreliable, and it might fill up the database with garbage. In order to support module ownership (assigning instances of your module to groups for example) and module customization, take a look at Module Customization and Ownership sections bellow for the changes you need to make to your data model. Utility Functions All the tcl functions you write for your module should go to your private tcl directory (e.g. faq module has it's tcl functions stored in faq-defs.tcl) and should be prefixed with the module name or it's abbreviation (e.g. faq_maintaner_p). If you think you wrote a really generic tcl function that everybody can benefit from, then you can send e-mail to philg@mit.edu and ask for your function to become a part of Arsdigita Toolkit utility functions.

Module Documentation

Every module should have it's documentation in html format in /doc directory (e.g. /doc/faq.html for faq module). This documentation is primarily intended for programmers and should be brief and technical as necesssary. It should list the features that this module provides, explain purpose of the module and it's possible uses, and discuss design decisions. For good example of documentation, take a look at /doc/chat.html.

Module Customization

A good, reusable module will be used in many Arsdigita installations and it may be required to perform a slightly different funcionality then the default one. A way to customize a module, so that it can be configured to support several different modes of operation is through usage of parameters. There are two levels at which the module can be customized: module and instance level. Module Level Customization Module customization includes parameters that are used by every instance of the module. These parameters should be put in configuration file your_server_name.ini in the parameters directory. For download module, parameters in configuration file look like this:
[ns/server/photonet-dev/acs/download] ; root directory of the downloadable files DownloadRoot=/web/photonet-dev/download/
These parameters can be accessed from within the code using ad_parameter function. Instance Level Customization Note that not all modules support multiple instances. For example, you can have at most one instance of eccomerce module per installation. For modules that support multiple instances, parameters should be columns in table where module instances are defined. For example, instances of chat module are chat rooms and parameters such as moderated_p (determines whether chat room should be moderated) are kept in chat_rooms table. This way parameter moderated_p is associated with an instance of the chat module and not chat module as a whole. When using parameters, you should make decision whether parameter should be associated with module and therefore put in parameters file or associated with a particular instance of the module and kept in the database.

Module Ownership

Standards for module ownership have been introduced in Arsdigita toolkit release 3.0. Before release 3.0, very few modules supported ownership, such as address book module, which provided an address-book instance for each user, effectively making user the owner of the address book. Notice that it makes sense only the modules supporting multiple instances ca In order to be able to use The acs_modules table in /doc/sql/modules.sql stores information about the acs modules (news, bboard, ...)
create table acs_modules (
	module_key		varchar(30) primary key,
	pretty_name		varchar(200) not null,
	-- this is the directory where module public files are stored. 
	-- for the news module public_directory would be /news
	public_directory	varchar(200),
	-- this is the directory where module admin files are stored
	-- for the news module admin_directory would be /admin/news
	admin_directory		varchar(200),
	-- this is the directory where system admin files are stored 
	-- notice that this is not always same as the admin_directory
	-- e.g. ticket module has admin directory /ticket/admin and
	-- site admin directory /admin/ticket
	site_wide_admin_directory	varchar(200),
	-- if module_type=system, this module has all: public, admin and site_wide admin pages (e.g. faq, news)
	-- notice that often admin and site_wide admin directory are merged together
	-- if module_type=admin, this is admin module and has no public pages (e.g. display, content_sections)
	-- notice that modules of this type have no public pages
	-- if module_type=site_wide_admin, this is module for site wide administration of another module (e.g. news_admin, bboard_admin)
	-- notice that having admin module for another module allows us to assign administration of modules to user groups
	-- in this case public_directory will correspond to the directory where files for site wide administration of that
	-- module are stored and admin_directory and site_wide_admin_directory are irrelevant 
	module_type                    varchar(20) not null check(module_type in ('system', 'admin', 'site_wide_admin')),
	-- does module support scoping
	supports_scoping_p	char(1) default 'f' check(supports_scoping_p in ('t','f')),
	-- this is short description describing what module is doing	
	description		varchar(4000),
	-- this is url of the html file containing module documentation
	documentation_url	varchar(200),
	-- this is url of the file containing date model of the module
	data_model_url		varchar(200)
);

tarik@arsdigita.com