WimpyPoint was born as a standalone application, started by Philip Greenspun in late December, 1997 and later enhanced by Krish Menon. WimpyPoint was rewritten by Jon Salz and reborn as an ACS module in late 1999, as a term project for MIT's 6.916: Software Engineering of Innovative Web Services class.
For more general information, see the the user-level help pages.
Data Model
Styles
The standalone WimpyPoint provided only limited style support: it allowed users to select from a limited set of CSS style sheets to associate with each presentation. Users can now maintain their own repositories of styles. Each style is a row in the wp_styles table. Users can provide colors (stored in table columns in the form 192,192,255) and optionally background image.
A style can be marked public, meaning that every user can view it. (For instance, the "Default (Plain)" style is public.) The UI does not provide any mechanism for styles to be marked public (administrators should just use SQL*Plus to change public_p).
Note that the wp_styles and wp_style_images tables are interdependent, so if you wanted to drop either table you'd need to use the CASCADE CONSTRAINTS option to DROP TABLE.
The style mechanism has much more general applicability than just to WimpyPoint - it might be useful in the future to abstract this out somehow to provide cross-module style-editing support.
Versioning
The data model is complicated significantly by versioning support, which allows the owner of a presentation to freeze the slide set (and later view previous versions, or revert to them). Each presentation is associated with a nonempty set of "checkpoints," each a row in the wp_checkpoints table. Each slide is associated with the range of checkpoints [min_checkpoint, max_checkpoint) in wp_slides (a max_checkpoint of NULL corresponds to infinity, i.e., the latest version).
In general, when a slide is edited and hasn't been changed since the latest checkpoint, we make a new copy of the slide and fiddle with the (min|max)_checkpoint of the old and new slide; when a slide is deleted, we just set max_checkpoint to the current checkpoint (so it becomes invisible in the most recent "view"). See slide-edit-2 and slide-delete-2 for examples.
When a slide set is frozen, we preserve the sorted order of the slides in wp_historical_sort. Without this facility, in order to maintain the versioning abstraction, whenever a user reordered slides in a versioned presentation we'd have to recopy all the slides (defeating the incremental nature of our versioning implementation).
The wp_(previous|next)_slide functions determine the slide before/after a particular slide when viewing the slide set at a particular checkpoint (a v_checkpoint of NULL) corresponds to the latest version).
wp_set_checkpoint and wp_revert_to_checkpoint do pretty much what you'd think.
Access Control
Access control is handled using ACS groups. The wp_access function determines, given a user's ID (or NULL for an anonymous user and some fields from wp_presentations, what privileges the user has with respect to the presentation.
Tcl Definitions
This was a term project, so I () was eager to do something interesting from an engineering standpoint, and went maybe a little overboard with the abstractions involved. I don't think these are bad abstractions per se - they consolidate code which, while taking 6.916, I found myself writing over and over - but in retrospect maybe using abstraction so heavily is not The ACS Way(tm).
wp_select, a control structure, takes the place of the usual ns_db select/ns_db getrow/set_variables_after_query loop. You can do:
wp_select "select foo, bar from whatever" {
ns_write "
$foo, $bar\n"
} else {
ns_write "
nothing selected\n"
}
wp_prepare_dml, given a table name, and names and values of columns, prepares an UPDATE or INSERT statement. In general, this facilitates the consolidation of pages which add records and edit existing records (e.g., slide-edit-2 and slide-add-2 are wrapped into slide-add). This is useful since -add and -edit pages often have to do the same kind of input validation anyway.
wp_clob_dml applies an INSERT or UPDATE DML statement (such as that prepared by wp_prepare_dml), optionally with up to three CLOBs provided in a list.
wp_try_dml and wp_try_dml_or_break try to execute a DML statement but generate an appropriate error message if it fails. (wp_try_dml_or_break additionally does a return -code return in this case.)
wp_only_if returns certain text if a condition is true, else other text. This is useful for embedding in long strings, e.g.:
ns_write "
... stuff ...
wp_header, given an ad_context_bar-style argument list, generates the entire header for a page. The title is simply the last element of the argument list. Your Workspace is included in the header only if the user is currently logged in.
wp_header_form is just like wp_header, except that the first argument contains attributes to insert into a tag placed at the top of the page. (We always insert at the very top of a page because placing it anywhere else results in unsightly extra white space.)
wp_slider generates a slider given a list of options. It's typically used like this: