WimpyPoint
part of the ArsDigita Community System
by Philip Greenspun and
Jon Salz
History
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 (Jon) 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 $db "select foo, bar from whatever" {
ns_write "<li>$foo, $bar\n"
} else {
ns_write "<li>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 ...
<option [wp_only_if { $id == 1 } "selected"]>Nummer Eins
<option [wp_only_if { $id == 2 } "selected"]>Nummer Zwei
... more 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 <form> tag placed at the top
of the page. (We always insert <form> 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:
ns_write [wp_slider "age" $age \
[list [list 7 "Week Old"] [list 30 "Month Old"] [list all "All"]]]
philg@mit.edu
jsalz@mit.edu