I have taken a little bit of time to look at Martijn Faassen's ZFormulator product, and here are some findings: ZFormulator is a product that allows you to create self-validating HTML forms without hand-coding HTML form element constructs in DTML methods/documents. It allows you to use the Zope UI to set validation constraints on form input, to resize form elements, etc. Your role after creating the ZFormulator object in constructing a basic form is limited to calling the ZFormulatorForm object within DTML to get all the form elements, and setting a target action method for the form. - Martijn includes a .zexp file for demo purposes in the product which gets placed into the import directory upon untarring the product file. I think this is OK, but I wonder if anybody else has thoughts on the implications of placing stuff into directories other than the intended product directory within a product tarball? For instance, I would consider it bad form for a Product to expand something into the lib/python/OFS directory. Others might disagree. What about products just going right ahead and creating instances of their classes within the ZODB upon installation? Or products automatically importing demo .zexp (or equivalent) files into the App object? Bad form or no? - The owner and group of all Martij's product files are martijn/martijn. We had some talk lately about how untarring Products into the directory tree might lead to the unintended resetting of permissions. When I untarred the product, all the files were reset to owner/group mcdonc/mcdonc (my user login). I do not know under what circumstances tar creates files which have their permissions set to their build filesystem's permissions, or whether this is a behavior endemic to non GNUtar tar variants or what. I seemed to have no problem with gunzip ZFormulator.tgz, tar xvf ZFormulator.tar within the Zope homedir. Does anybody have any tips as to when tar decides to write files out with their original owner/group bits set instead of owner/group set to the untarring user? (yes, I am way too lazy to try to decode the WORST man page in history, the GNUtar manpage). - ZFormulator is a good example of how to create a folderish object within a Python product that constrains addable meta-types to certain other object types. In Martijn's product, he creates a base class named Form that inherits from ObjectManager, RoleManager, and SimpleItem. Since the Form base class inherits from ObjectManager, it is folderish. He overrides ObjectManager's all_meta_types method, and though I can't quite follow the logic as to how he populates the meta_types list within the class, it works, constraining the addable meta_types to those he chooses in a registration function (in this case, the individual field types, such as checkbox, textarea, etc.) I learned some tricks from this. One of the unintuitive things about constraining addable objects this way is that a ZFormulatorForm instance's Security tab still shows permission descriptions for aquired object types (such as Folders, etc). Not a really big deal, but sure to confuse some people. - The UI of ZFormulator is pretty standard, first you create a ZFormulatorForm object (this is an object that is represented by the Form class) by choosing it from the addable object dropdown. Then you click on that object to start messing with it. While you're messing around with it, you can add BasicFields, TextboxFields, CheckboxFields, and a bunch of other form widgets inside the Form. Each object type has its own icon (nice!) and each object type corresponds to a different object class (e.g. the TextareaField class, the CheckboxField class, etc.) You create the form widget object through the standard Zope management interface through the add dropdown. After you've done that, you navigate to the form object by clicking on it and redefining its properties. One thing that I'm sort of on the fence about is calling MessageDialog when properties for objects are changed. Martijn does this for most all changes within the UI. I sometimes find that this gets old after a while ("Yes, I know, thanks, I changed the object properties.") There isn't really much of a standard within Zope about calling MessageDialog (for example, SQL method Edit properties, when changed, don't call MessageDialog, they instead put a "last changed" blurb at the top of the management screen). Any comments? Additionally, what if a person were to create a Wizard-style interface for the addition of forms and form elements. Martijn has taken the approach of creating forms and form elements one-at-a-time via the Zope UI, but I could easily see a multipart form Wizard that would lead a user through the creation of a form and its elements without him or her knowing that he/she is instantiating things within the ZODB. Thoughts? - Martijn defines something like 27 classes that live within his product. Each of these classes, for the most part, is defined in a separate Python module within the product directory. I don't mind this at all. Anybody have anything to say about that? - I don't really want to get too deep into reviewing code here, so I'm just going to report errors and things that I think are a tiny bit askew (:-))... within a ZFormulator form, when adding a *second* instance of the same type of object (for example, a second TextareaField), I intermittently got an AttributeError, "None" object has no attributes coming from Field.py line 138 in _setSheet. Martijn, I would also give a little blurb as to what "Order" means within the Form elements add and edit UI as its not immediately obvious (I figured it out by reading the code). The View button between form elements produces inconsistent results (for example, a checkbox returns quoted HTML of the form element, while a textarea View shows the default value for the form element without any HTML). Also, the ListField input box for the list elements should probably be split into separate key/value fields instead of using the pipe as a separator between key and value within a textarea. I know SQL integration is a "work in progress", and doesn't actually do much yet. I'd almost be apt to leave it out of the product entirely as it's sort of hurts my brain to think about where my form values are coming from and going to in the context of using the product as a SQL conduit. Also, when navigating with the back-forward buttons within a browser between forms created using ZFormulator (even within the ZFormulator UI which "eats its own dogfood"), browser errors indicating that form responses have expired are common. I imagine this is a pretty tough one to avoid, and I haven't looked at the code closely enough to see why it happens with ZFormulator forms more often than with Zope HTMLFile-derived forms. Nice product Martijn! Well done! -- Chris McDonough Digital Creations, Inc. Zope - http://www.zope.org