OpenACS &version; Packages
By Pete Su and Bryan Quinn
Overview
This document is a guide on how to write a software package for
OpenACS. OpenACS packages are installed and maintained
with the OpenACS Package Manager (APM). This document presents reasons
for packaging software, conventions for the file system and naming
that must be followed, and step by step instructions for creating a
new package for the "Notes" example package.
Why package your software?
To answer this question, we should examine how OpenACS servers were
organized in the past. We will assume throughout this document that
the page root for your server is called ROOT. In OpenACS
3.2.x and earlier, a typical server might have a file system behind it
that looked something like this:
ROOT/
bin/
parameters/
ad.ini
tcl/
core tcl libraries here
www/
admin/
bboard/
site wide admin for bboard
intranet/
site wide admin for intranet
... and so on for all modules ...
bboard/
pages for bboard
admin/
other admin pages for bboard
intranet/
pages for bboard
admin/
other admin pages for intranet
doc/
documentation
sql/
core and application data models here
... and so on for all modules ...
In previous versions of OpenACS, you wrote a new application like this:
Put all Tcl library procedures under
server-root/tcl.Put all User viewable content under
server-root/www.Put all Admin content under /admin/package-key/.
This structure is very simple, and worked well in a world where
OpenACS was basically a single monolithic entity. But, this organization
made it difficult to distribute modules as independent packages, because
the pieces of each module are strewn all over the tree in at least 3
or 4 different areas.
Here is how an OpenACS &version; server is laid out:
ROOT/
bin/
packages/
acs-admin/
acs-api-browser/
acs-content-repository/
acs-core-docs/
acs-developer-support/
acs-kernel/
acs-ldap-authentication/
acs-messaging/
acs-subsite/
acs-templating/
acs-test-harness/
acs-util/
acs-workflow/
bboard/
bboard.info
sql/
oracle/
oracle data model
postgresql/
postgresql data model
tcl/
tcl library code
www/
admin/
administration pages
other pages
doc/
documentation
message-catalog/
news/
notification/
page/
tcl/
bootstrap code
www/
misc pages
Note that a major reorganization has happened here. The diagram only
expands the structure of the bboard/ package directory,
but all the others are basically the same. Each package encapsulates
all of its data model, library code, logic, adminstration pages and
user pages in a single part of the file tree. This organization has
two major advantages:
This structure makes it easy for developers to track
down everything that is related to a
particular package without hunting all over the file system.
Encapsulating everything
about a package in one place also makes it much easier to
distribute packages independently from the OpenACS itself.
In order to make this work, we need a system that keeps track of the
packages that have been installed in the server, where those packages
have been installed, and a standard way to map URLs that a client
sends to our server to the right page in the appropriate
package. While we're at it, this tool should also automate
package installation, dependency checking, upgrades, and package
removal. In OpenACS &version;, this tool is called the APM.
The APM
The APM is used to create, maintain, and install packages. It takes
care of copying all of the files and registering the package in the
system. The APM is responsible for:
Package registrationAutomatic installation of packages: loading data models, code
libraries, and so on.Checking what packages depend on what other packages.Storing information on the package including ownership and a file
list.
In addition for packages that are applications, the APM is responsible
for keeping track of where in the site a user must go in order to use
the application. To do this, the APM defines a set of objects that we
call package instances. Once a package is loaded, the
administrator can create as many instances of the package as she
likes, and map these instances to any URL in the site that she
wants. If packages are analogous to executable programs in an
operating system, then package instances are analgous to multiple
running copies of a single program. Each instance can be independently
administered and each instance maintains its own set of application
parameters and options.
The following sections will show you how to make a package for the
Notes application. In addition, they will discuss some new site
management features in OpenACS &version; that take advantage of the APM's package
instance model. The two most important of these are subsites,
and the site map tool, which can be used to map applications to
one or more arbitrary URLs in a running site.
We will also discuss how to organize your files and queries so
they work with the OpenACS Query Dispatcher.
What a Package Looks LikeOpenACS Package
To illustrate the general structure of a package, let's see what the
package for the "notes" application should look like. This is shown in
the diagram below:
ROOT/
+-- packages/ APM Root
|
+-- notes/ Package Root
| |
| |
| +-- sql/
| | |
| | +-- oracle/
| | | |
| | | +-- notes-create.sql Data Model Creation Script for Oracle
| | | +-- notes-drop.sql Data Model Drop Script
| | | +-- *.sql Data Model Files
| | | +-- upgrade/
| | | +-- upgrade-4.1-4.5.sql Data Model Upgrade Scripts
| | +-- postgresql/
| | | |
| | | +-- notes-create.sql Data Model Creation Script for PostgreSQL
| | | +-- notes-drop.sql Data Model Drop Script
| | | +-- *.sql Data Model Files
| | | +-- upgrade/
| | | +-- upgrade-4.1-4.5.sql Data Model Upgrade Scripts
| +-- tcl/
| | |
| | +-- notes-procs.tcl Tcl Library
| | +-- notes-procs.xql SQL92 Queries for notes-procs.tcl
| | +-- notes-procs-oracle.xql Oracle-specific queries for notes-procs.tcl
| | +-- notes-procs-postgresql.xql PostgreSQL-specific Queries for notes-procs.tcl
| | +-- notes-init.tcl Tcl Initialization
| | +-- notes-init.xql Queries for notes-init.tcl (work in all DBs)
| | +-- *.tcl Tcl Library Files
| +-- www/
| | |
| | +-- admin/ Administration UI
| | | +-- tests/ Regression Tests
| | | | +-- index.tcl Regression Test Index Page
| | | | +-- ... Regression Tests
| | | +-- index.tcl Administration UI Index Page
| | | +-- ... Administration UI Pages
| | |
| | +-- doc/ Documentation
| | | +-- index.tcl Documentation Index Page
| | | +-- ... Administration Pages
| | +-- index.tcl UI Index Page
| | +-- index.adp UI Index Template
| | +-- index.xql Queries for UI Index page
| | +-- *.tcl UI Logic Scripts
| | +-- *.adp UI Templates
| | +-- *-oracle.xql Oracle-specific Queries
| | +-- *-postgresql.xql PostgreSQL-specific Queries
| +-- notes.info Package Specification File
+-- Other package directories.
All file locations are relative to the package root, which in this
case is ROOT/packages/notes. The following table
describes in detail what each of the files up in the diagram contain.
File TypeIts UseNaming ConventionData Model Creation Script
Contains the SQL that creates the necessary data model and
PL/SQL packages (or PL/pgSQL or whatever) to support the
package. The name must match the convention below or the
package will not be installed correctly. Notice that
the script must be under the appropriate directory for
the database you are developing your package for
(hopefully all OpenACS-supported databases :-))
sql/<database>/notes-create.sqlData Model Drop ScriptContains the SQL that removes the data model and PL/SQL
packages generated by the creation script. The name must
match the convention below or the package will not be
installed correctly.
sql/<database>/notes-drop.sqlData Model FileAny .sql file that does not match the naming convention above
is recognized as a data model file. It is useful to separate
the SQL in the creation and drop scripts into several
files and then have the scripts source the other data model
files. In Oracle this can be done by including
@@ filename in the creation or drop
scripts. See the
Oracle SQL*Plus documentation for examples. In
PostgreSQL the same is acomplished by including \i.
sql/<database>/*.sqlData Model Upgrade Scripts
Contain changes to the data model between versions. The APM
can automatically load the appropriate upgrade scripts when
upgrading to a new version of a package.
sql/<database>/upgrade/upgrade-<old>-<new>.sql
SQL92 Query Files
Files with queries that are supported by all
databases. These are usually SQL92 queries. Notice that
the .xql filename must match the name of the .tcl file
that uses those queries.
*.xql
Oracle-specific Query Files
Files with queries that are Oracle-specific. Notice that
the .xql filename must match the name of the .tcl file
that uses those queries.
*-oracle.xql
PostgreSQL-specific Query Files
Files with queries that are PostgreSQL-specific. Notice that
the .xql filename must match the name of the .tcl file
that uses those queries.
*-postgresql.xql
Tcl Library Files
The Tcl library files include a set of procedures that provide
an application programming interface (API) for the package to
utilize.
tcl/notes-procs.tclTcl InitializationThe initialization files are used to run Tcl procedures that
should only be sourced once on startup. Examples of
statements to put here are registered filters or procedures.
Tcl initialization files are sourced once on server startup
after all of the Tcl library files are sourced.
tcl/notes-init.tclAdministration UIThe administration UI is used to administer the instances of
the package. For example, the bboard administration UI is
used to create new forums, moderate postings, and create new
categories for bboard postings.www/admin/*Administration UI Index PageEvery package administration UI must have an index page. In
most cases, this is index.tcl but it can be
any file with the name index, such as
index.html or index.adp.www/admin/index.tclRegression TestsEvery package should have a set of regression tests that
verify that it is in working operation.
These tests should be able to be run at any time after the package has
been installed and report helpful error messages when there is
a fault in the system.www/admin/tests/Regression Test Index PageThe regression test directory must have an index page that
displays all of the tests available and provides information
on how to run them. This file can have any extension, as long
as its name is index./www/admin/tests/index.htmlDocumentationEvery package must include a full set of documentation that
includes requirements and design documents, and user-level and
developer-level documentation where appropriate./www/doc/Documentation Index PageThe documentation directory must include a static HTML file with the name
of index.html./www/doc/index.htmlUI Logic ScriptsPackages provide a UI for users to access the system. The UI
is split into Logic and Templates. The logic scripts
perform database queries and prepare variables for
presentation by the associated templates./www/*.tclUI TemplatesTemplates are used to control the presentation of the UI.
Templates receive a set of data sources from the logic scripts
and prepare them for display to the browser./www/*.adpUI Index PageThe UI must have an index page composed of a logic script
called index.tcl and a template called
index.adp./www/index.tclPackage Specification FileThe package specification file is an XML file generated and
maintained by the OpenACS Package Manager (APM). It specifies
information about the package including its parameters and its
files.notes.infoMaking a Package
Here is how you make a package.
Login as a site-wide administrator on your web service.
Go to the package manager on your server. The URL is /acs-admin/apm.
Click on the link /acs-admin/apm/package-add.
Fill out the form for adding a new package. The form explains what
everything means, but we'll repeat the important bits here for easy
reference:
Package Key
This is a short text string that should uniquely name your package to
distinguish it from all the others. It is used as a database key to
keep track of the package and as the name of the directory in the file
system where all the files related to your package will live. Example
package keys in the current system include: bboard,
acs-kernel and so on. For the example application, we
will use the package key notes.
Package Name
This is a short human readable name for your package. For our example,
we will use the name "Notes".
Package Plural
If your package name is a nice singular noun, this should be the
plural form of it. I assume the plural form is used when multiple
instances of the package are used by a single service. We'll talk more
about package instances later. Our example apllication doesn't really
have a good plural name. So just make it also be "Notes".
Package Type
Generally we think of packages as either being applications,
meaning that the package is meant primarily for use by end-users, or
services meaning that the package is meant to be a reusable
library of code, to be used by other packages. bboard is
a good example of an application, while acs-templating is
a good example of a service. Our example is an application, so pick
that.
Package URL
The URL from which people will download your package when it is
done. Just use the default for this, you can change it later.
Initial Version
Just use the default here, which by convention is 0.1d.
Version URL
Just use the default here.
Summary and Description
Enter a short summary and longer description of what the Notes
application will do. That is, something like "this application keeps
short textual notes in the database", and so on.
Click the button "Create Package".
At this point, APM will create a directory called
ROOT/packages/notes.
The directory that APM created will be empty except for the
notes.info file. Create a file
called
ROOT/packages/notes/sql/oracle/notes-create.sql. We'll
fill this file with our data model
very soon. Create a file called
ROOT/packages/notes/sql/oracle/notes-drop.sql. This
will contain the instructions to drop the data model. To be
complete, you would also create the PostgreSQL versions of these
files as well in
ROOT/packages/notes/sql/postgresql/notes-create.sql
and
ROOT/packages/notes/sql/postgresql/notes-drop.sql.
After you do this, go back to the main APM page. From there,
click the link called "notes" to go to the management
page for the new package. Now click the link called "Manage
file information", then the "Scan the
packages/notes directory for
additional files in this package" link on that page to scan
the file system for new files. This will bring you do a page
that lists all the files you just added and lets you add them to
the notes package.
Note that while the .sql files
have been added to the packge, they have not
been loaded into the database. For the purposes of development,
you have to load the data model by hand, because while OpenACS
has automatic mechanisms for loading and reloading
.tcl files for code, it does not
do the same thing for data model files.
Now go back to the main management page for the notes
If your package has parameters, create them using the "Manage
Parameter Information" link.The new package has been created and installed in the server. At
this point, you should add your package files to your CVS repository.
I'll assume that you have set up your development repository according
to the standards described in
these instructions. If so, then you just do this:
% cd ROOT/packages
% cvs add notes
% cd notes
% cvs add notes.info
% cvs add sql
% cd sql
% cvs add *.sql
% cd ROOT/packages/notes
% cvs commit -m "add new package for notes"
Now you can start developing the package. In addition to writing code,
you should also consider the tasks outlined in the package submission guidelines.
The Site Map and Package Instances
At this point, you are probably excited to see your new package in
action. But, we haven't added any user visible pages yet. By
convention, user visible pages go in the
ROOT/packages/notes/www directory. So go there and add a
file called hello.html with some text in it. Now we have
to make the user pages visible in the site. Since we didn't put the
pages underneath ROOT/www they will not appear on their
own. What we have to do is mount the application into the site
map. That is, we have to define the URL from which the application
will serve its pages. This process is slightly more complex than in
OpenACS 3.x, but also much more flexible.
In OpenACS 3.x, everything in the site was implicitly mounted underneath
ROOT/www. AOLserver automatically took any URL like
/foo/bar/moo/baz.html and mapped it to the file
ROOT/www/foo/bar/moo/baz.html. This was conveniently
simple, but lacked flexibility. In particular, it was difficult to
map content that lived outside the page root into the site, and it was
also hard to map mulitiple URLs to the same place in the file system.
In OpenACS &version;, administrators can define an arbitrary mapping between the
URLs the user types and the actual file in the file system that is
served. This mapping is called the site map and entries in the
site map are called site nodes. Each site node maps a URL to an
OpenACS object. Since package instances are objects, the site map allows
us to easily map package instances to URLs. As we said before, each
instance of an application has its own set of parameters and
runs from its own URL within the site. What this means is that even
though all the code for the notes application lives in
ROOT/packages/notes, the application itself can run from
any number of locations in the site. This allows developers and
administrators to build sites that look to the user like a collection
of many indedendent applications that actually run on a single shared
code base. The request-processor document shows
you how OpenACS figures out which instance of your application was
requested by the user at any given time. The page development tutorial shows you how to use this
information in your user interface.
In order to make the new notes application visible to
users, we have to mount it in the site map. You do this by going to
the Site Map page, which is by
default available at /acs-admin/site-map. Use the
interface here to add a new sub-folder called notes to
the root of the site, then click "new application" to mount a new
instance of the notes application to the site. Name the
new instance notes-1.
Then type this URL into your browser:
http://your-server.your-domain.com/notes/hello.html
Now you should see the contents of the page that you added. What has
happened is that all URLs that start with /notes have
been mapped in such a way as to serve content from the directory
ROOT/packages/notes/www. At this point, you can
experiment with the site map by mounting multiple instances of the not
yet written Notes application at various places in the site. In a
later document, we'll see how to write your application so that the
code can detect from what URL it was invoked. This is the key
to supporting subsites.
Summary
The APM performs the following tasks in an OpenACS site:
Manages creation, installation, and removal of packages from the
server. Also keeps track of what files belong to which packages.
Manages package upgrades.
Manages information on all package instances in a site. For
correctly written application packages, this allows the site
administrator to map multiple instances of a package to URLs within a
site.
Writes out package distribution files for other people to download and
install. We'll cover this later.
Additional ReadingPackage submission guidelines($Id: packages.xml,v 1.5.2.1 2003/04/29 05:59:02 joela Exp $)