Note: Versions 0.3 and up are a complete rewrite, and may make some of the information following incorrect. The general idea of XMLWidgets is still the same, however.
I'm working on a way for end-users to do wysiwyg-like editing of structured XML Documents. To accomplish this I need a very flexible way to display these XML Documents in HTML, and also a good way for the displayed document to respond to user input.
For example: Users should be able to
focus a paragraph they want to
modify. If they then press an
edit button, the selected paragraph
becomes a textarea, allowing the user to change the contents of the
One can accomplish this kind of functionality with a large amount of DTML methods, possibly assisted by some external methods. The problem with this is however is that it is:
- quickly becomes completely unmanagable.
XMLWidgets are written in Python (though they could in the future be combined with DTML methods). Rendering XML Documents with XMLWidgets seems to be faster than a DTML only solution. More important, however, is that XMLWidgets make the design of complicated dynamic XML renderings more manageable than a DTML solution can be. A disadvantage is that one needs to write Python code in a product to work with them, but this can be done in a much more structured fashion than in the case of DTML solutions -- far less special casing is necessary.
The Idea behind XMLWidgets
The basic idea behind XMLWidgets is that one can see the process of rendering an XML Document to HTML as the translation of individual XML nodes to widgets.
A widget is a term in graphical user interface talk; it may be a button, a textual label, an area where you can type text, etc. Basically any component of a user interface can be seen as a widget.
A widget has two main functions. One is that it can render itself (somewhere in a window, usually). The other thing that many widgets can do is receive and handle events. An event may be the click of the mouse on a button, or the submission of text data, etc.
What I wanted to accomplish was a way to automatically translate an XML Document to a dynamic HTML page. The HTML page would not only have to display the XML document in a nice way (rendering it), but also be able to respond to user events.
XMLWidgets does this by defining a translator object and the set of widgets involved in this XML to HTML translation. The translator object has a map which lists which XML node (type and name) maps to which widget. Each widget defines a render() method which produces HTML, and each widget can also define a set of event methods, that are called when the user manipulates the rendered widget in certain ways (for instance when the user clicks on a hyperlink).
An event such as a click on a particular hyperlink is automatically passed back to a predetermined method of the widget that was used to render the document. The particular node that was displayed by that widget is passed to the event handling method as well. After an event is handled, the XML Document will be rerendered and redisplayed, so that the result of the event becomes visible.
An event can have two main results. The first is that the translation map
can be altered dynamically. One can select a particular XML Node this way
amongst its siblings of the same type and name, for instance, by letting a
different XML Widget render it. Visually this may mean that one paragraph
focused (for instance in grey), while all other paragraphs
are rendered in the default way.
The other possible result of an event is a change in the structure of the XML Document itself. For instance, node contents such as text or attribute values can be altered. Nodes may be added or removed. nodes can be added or removed. Because the XML Document is rerendered after each event, the user can instantly see the changes.
How to use XMLWidgets?
Currently, the only way to use XMLWidgets is to write your own Python base class for a ZClass. Some examples for this are included in the XMLWidgets distribution. You derive your own class from XMLWidgetManagerBase which does most of the work, so it may not be as difficult as it seems. Study the examples and read the source for more information.