<html>
<!--AD_DND-->
<head>
<title>ACS Modules</title>
</head>

<body bgcolor=#ffffff text=#000000>
<h2>ACS Modules</h2>

part of the <a href="index.html">ArsDigita Community System</a>
by <a href="mailto:tarik@arsdigita.com">Tarik Alatovic </a> 

<hr>

<h3>The Big Picture</h3>

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 <i>common and
reusable</i> functionality. Examples of modules in Arsdigita toolkit
are News, Bulletin Board, Address Book and Ecommerce modules.


<h3>Module Architecture</h3>

<b>Directory Structure</b>

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.
  
<b>Data Model</b>

Data model for the module should reside in /doc/sql directory
(e.g. /doc/sql/faq.sql for faq module). 
<a href=http://photo.net/sql/data-modeling.html>Data modeling</a> 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.

<b>Utility Functions</b>

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 <a href=mailto:philg@mit.edu>philg@mit.edu</a> and ask for
your function to become a part of Arsdigita Toolkit utility functions.


<h3>Module Documentation</h3>

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 <a
href=/doc/chat.html>/doc/chat.html</a>.

<h3>Module Customization</h3>

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. 

<b>Module Level Customization</b>

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:
<blockquote>
[ns/server/photonet-dev/acs/download]
; root directory of the downloadable files
DownloadRoot=/web/photonet-dev/download/
</blockquote>
These parameters can be accessed from within the code using ad_parameter function.

<b>Instance Level Customization</b>

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.


<h3>Module Ownership</h3>

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 <a href="/doc/sql/display-sql.tcl?url=/doc/sql/modules.sql">/doc/sql/modules.sql</a> stores information about the acs modules (news, bboard, ...)

<blockquote>
<pre>
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)
);
</blockquote>
</pre>

<hr>

<a href=mailto:tarik@arsdigita.com><address>tarik@arsdigita.com</address></a>
</body>
</html>