Page: http://wiki.cocoondev.org/Wiki.jsp?page=WoodyTODO , version: 2 on Fri Jul 25 11:52:50 2003 by BrunoDumon
- * (high) caching of FormDefinitions by the DefaultFormManager - * The types of widgets, datatypes and validation rules should be taken from external configuration files. Currently they are hardcoded. + * evaluate other, more standard, expression engines such as Jexl and JXPath and compare with the currently used xreporter-expression package. + * Add an setValidationError or addValidationError method to the Widget interface - * extend supported datatypes (most notably with date and decimal), and add more validation rules (regexp check for strings, ...) - * The "action" and "method" attributes on the html form element should be set by the WoodyTemplateTransformer, which gets them as parameter from the sitemap (because this is not a concern of the template designer, but of the sitemap designer) - !Design-level things - * Eventhandling (more written-out ideas to come) - * Generic mechanism for storing hidden form state (e.g. value of hidden fields, properties that are defined on a widget instance level instead of widget definition level), or maybe decide to just require to store the form instance in the session in that case - Page: http://wiki.cocoondev.org/Wiki.jsp?page=WoodyTemplateTransformer , version: 1 on Fri Jul 25 11:09:11 2003 by BrunoDumon New page created: + !!!WoodyTemplateTransformer + + The WoodyTemplateTransformer (simply "woody transformer" from now on) makes it possible to define the layout for your form without having to write a seperate XSLT for each form. If you prefer to do everything with XSLT, you have also the option of using the WoodyGenerator. + + The basic principle is that the woody transformer will replace any <wt:widget id="xyz"/> elements by the XML representation of the corresponding widgets. These wt:widget elements can be embedded in e.g. a HTML layout. So after passing this template through the woody transformer you'll end up with HTML with here and there a piece of XML describing a widget. This XML description contains all state information of the widget: its value, validation errors and selection-list data if any, and so on. These widget-XML-descriptions will then typically be translated to HTML by an XSLT. This XSLT is then however not form-specific, as it simply needs to know how to translate individual widgets to HTML, and does not have to create the complete page layout. Woody contains just such an XSLT so you don't have to write it yourself (at the time of this writing, this XSLT is still quite simple). The image below illustrates this process. + + [http://outerthought.net/~bruno/images/woody_template_transformer.png] + + !!Where the woody transformer looks for the Woody form object + + Each time the woody transformer encounters a wt:form-template element (see further on), it will try to retrieve a woody form instance object. It looks for it in the following locations: + + # if the wt:form-template element has a location attribute, then the value of that attribute will be evaluated as a JXPath expression. The result of this expression should be the form object. + # if a parameter called "attribute-name" was supplied to the woody transformer in the sitemap, then the woody transformer will try to find the form in the request attribute with that name. (request attributes are a temporary storage area that exists for the duration of one request and is often used to communicate objects between different sitemap components such as actions and transformers) + # finally, the woody transformer will look if a woody form was supplied from a flowscript using the key "woody-form". + + If the form is not found at any of these locations, an exception is thrown. + + !!!Woody transformer element reference + + The elements to which the woody transformer reacts are all in the "wt" (Woody Template) namespace, which is identified by the following URI: + + {{{ + http://apache.org/cocoon/woody/template/1.0 + }}} + + These will generally be replaced by elements in the "wi" (Woody Instance) namespace, which is identified by the following URI: + + {{{ + http://apache.org/cocoon/woody/instance/1.0 + }}} + + !!wt:form-template + + The wt:form-template element is always required; all other wt:* elements should occur inside a wt:form-template element. As described earlier, when the woody transformer encounters the wt:form-template element it will try to look up the woody form instance object. + + wt:form-template elements may not be nested. + + The wt:form-template will by default copy over all attributes appearing on it, except for one attribute called "location", and it will also take special care of the action attribute. + + The __action attribute__ can contain JXPath expressions. As with the JXTemplateGenerator, these JXPath expressions must be embedded inside #{ and }. By allowing the use of JXPath expressions, you can embed dynamic data in the action attribute. One of the most common uses is to embed the continuation id (if you're using flowscript), for example: + + {{{ + <wt:form-template action="#{$continuation/id}.continue" ... + }}} + + The following objects are available in the JXPath context: continuation, requests, session and parameters. The context of the JXPath expression is the map passed on from the flowscript (if any). + + The __location attribute__, if present, is used to retrieve the form instance object. The value of the location attribute should be a JXPath expression, and is executed in the same context as the JXPath expressions embedded in the action attribute. + + For example, if your form object is stored in the session using the key "myform", then following expression in the location attribute can be used to retrieve it: + + {{{ + <wt:form-template location="getAttribute($session, 'myform')" ... + }}} + + If you'd like to retrieve the key "myform" from a parameters specified in the sitemap, say one called "sessionattr", then the following can be used: + + {{{ + <wt:form-template location="getAttribute($session, getParameter($parameters, 'sessionattr'))" ... + }}} + + As mentioned before, wt:form-template elements cannot be nested, but you can have multiple wt:form-template elements on one page. Together with the location attribute, this can be used to handle multiple forms occuring on one template. + + !!wt:widget + + The wt:widget element is replaced by the woody transformer by the XML representation of a widget. Which widget is specified by the id attribute. If the wt:widget element has any content, it will be embedded in the resulting element inside a wi:styling element. + + For example, the following: + {{{ + <wi:widget id="somefield"> + <list-style>listbox</list-style> + </wi:widget> + }}} + + will be replaced by: + {{{ + <wi:field id="somefield" [...] > + [...] + <wi:styling> + <list-style>listbox</list-style> + </wi:styling> + </wi:field> + }}} + + (assuming it is a "field" widget) + + !!wt:widget-label + + The wt:widget-label element will be replaced by the woody transformer by the label of a certain widget (specified by an id attribute). The label will not be wrapped in another element. + + !!Working with repeaters: wt:repeater-widget, wt:repeater-widget-label, wt:repeater-size + + The wt:repeater-widget element is similar to the wt:widget element but provides special treatement for repeaters. The content of the wt:repeater-widget element will be used as a template to generate each of the rows of the repeater. + + The wt:repeater-widget-label element is used to retrieve the the label of a widget contained by a repeater. It requires two attributes: id (identifying the repeater) and widget-id (identifying the widget in the repeater). + + The wt:repeater-size element inserts an element <wi:repeater-size id="..." size="..."/> containing the size (number of rows) of the repeater. + + For an example of how this all fits together, take a look at the samples included in the woody block. + Page: http://wiki.cocoondev.org/Wiki.jsp?page=WoodySample , version: 4 on Fri Jul 25 11:38:26 2003 by BrunoDumon - A field widget can be associated with a datatype. The function of the datatype is to convert the string value entered by the user to a more specific type like a number or a date (and vice versa, convert them back to strings) (this part is now delegated to a seperate object: a Convertor). The datatype will also perform the validation. (This split-up between "widget" and "datatype" is specific for the field widget -- it is perfectly possible to make widgets that have nothing to do with datatypes). In this way, a field widget contains strongly-typed data. For example, if you associated a "long" datatype with a field widget, then you can be sure that when you retrieve the widget's value, you will get a Long object (that is, if the form was validated successfully). ? ^^^ + A field widget can be associated with a datatype. The function of the datatype is to convert the string value entered by the user to a more specific type like a number or a date (and vice versa, convert them back to strings) (this part is actually delegated to a seperate object: a Convertor). The datatype will also perform the validation. (This split-up between "widget" and "datatype" is specific for the field widget -- it is perfectly possible to make widgets that have nothing to do with datatypes). In this way, a field widget contains strongly-typed data. For example, if you associated a "long" datatype with a field widget, then you can be sure that when you retrieve the widget's value, you will get a Long object (that is, if the form was validated successfully). ? ^^^^^^^^ + + __Important note:__ this shows only one possible way to handle the form. You don't need to do things exactly as they are shown here. Another important alternative is the use of flowscript. The woody samples include multiple examples of how to use the flowscript integration. Page: http://wiki.cocoondev.org/Wiki.jsp?page=Woody , version: 4 on Fri Jul 25 11:57:09 2003 by BrunoDumon + In related news: + * [Sylvain|SylvainWallez] [compares XMLForm and Woody|http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=105881304808076&w=2]. + Page: http://wiki.cocoondev.org/Wiki.jsp?page=WoodyBinding , version: 1 on Fri Jul 25 11:47:59 2003 by BrunoDumon New page created: + !!!The binding framework + + Likely you will want to use Woody to "edit stuff", such as the properties of a bean or data from an XML document. This supposes that before you show the form, you copy the data from the bean to the form, and after the form has been validated, you copy the data in the form back to the bean. To avoid having to write actual code for this, a binding framework is available. + + The basic definition of a binding is as follows (if you don't know Java, just ignore this): + + {{{ + public interface Binding { + public void loadFormFromModel(Widget frmModel, Object objModel); + public void saveFormToModel(Widget frmModel, Object objModel); + } + }}} + + A binding can work with any object and can perform the binding in any possible way. Currently one implementation is available, based on JXPath. JXPath allows to address data in both beans and XML documents using XPath expressions, so this binding implementation can be used both with beans and XML documents. + + The binding is configured using an XML file. This XML file contains elements in the "wb" (Woody Binding) namespace. + + (more information to come -- for now look at the samples and possible source code or ask questions on the user mailing list) + Page: http://wiki.cocoondev.org/Wiki.jsp?page=CommandLine204 , version: 2 on Fri Jul 25 11:56:50 2003 by 138.102.1.123 Page: http://wiki.cocoondev.org/Wiki.jsp?page=WoodyIntro , version: 6 on Fri Jul 25 11:28:04 2003 by BrunoDumon - The basic thing that Woody provides is a Form object. This Form object could be seen as the server-side representation of a client-side form. The Form contains a number of widgets (and is in fact itself also a widget). When a form is submitted, you can call Form.processRequest(Request) to let it (and recursively all the widgets contained in it) read its state from the request. ? ^ ^^^^^^^^^^^^ + The basic thing that Woody provides is a Form object. This Form object could be seen as the server-side representation of a client-side form. The Form contains a number of widgets (and is in fact itself also a widget). When a form is submitted, you can call Form.process(FormContext) to let it (and recursively all the widgets contained in it) read its state from the request. ? ^^^^^^^^^ ^ - The Form object is something that is used by other code, such as an Action or a flowscript, to help in handling forms. Thus Woody will not take complete control of how requests are handled. Woody contains some default Actions to instantiate and process a form. + The Form object is something that is used by other (controller) code, such as an Action or a flowscript, to help in handling forms. Thus Woody will not take complete control of how requests are handled. Woody contains some default Actions to instantiate and process a form. Integration with flowscript is also available. ? +++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++ - As for the presentation of the form (i.e. creating the actual HTML form), Woody provides a WoodyTemplateTransformer. This avoids the need to spend braincycles on designing XSLT's to handle Woody's XML output formats if you just want to create a quick form. [[More details elsewhere] ? -------------------------- + As for the presentation of the form (i.e. creating the actual HTML form), Woody provides a [WoodyTemplateTransformer]. This avoids the need to spend braincycles on designing XSLT's to handle Woody's XML output formats if you just want to create a quick form. ? + + Page: http://wiki.cocoondev.org/Wiki.jsp?page=WoodyNotes , version: 3 on Fri Jul 25 11:48:45 2003 by BrunoDumon - - !Mappings or bindings for connecting forms to your data - - In the future, we envisage that there will be mapping (binding) mechanisms to handle the loading and storage of form data based on an XML description. These mappings could allow loading of data from a database record, a business bean or an XML document into the form. After the form validation cyclus has ended, it could then apply the users' changes back to the database record, business bean or XML document. But for now, you need to write some Java code to load data into the form and get the data from the form, but this is fortunately very easy (see examples further on). [[TODO] we could also provide an action that returns the value of all widgets as parameters to the sitemap, or provide an XSP taglib to retrieve them. Let us know if you would find this useful (or even better, provide a patch). -
