cocoon-docs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Cocoon Wiki] Update of "DesignPattern/FormGeneration" by JCKermagoret
Date Fri, 16 Sep 2005 05:37:27 GMT
Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Cocoon Wiki" for change notification.

The following page has been changed by JCKermagoret:
http://wiki.apache.org/cocoon/DesignPattern/FormGeneration

------------------------------------------------------------------------------
- ## page was renamed from ECrudDesignPattern-FormGeneration
- = Form generation =
+ = Intent =
+ "Write once, use many" paradigm applied to forms. Create form parts once, that you can aggregate
and reuse across many forms, in many applications without any neither change nor redundancy.
+ 
+ = Motivation =
+ Forms usually contains some identical information (System information, Author, Date and
time concepts, ...) and differ only a little from mode to mode (create, update, search, detail).
If we use forms framework in a quick approach, we usually define form (and configuration files)
for each mode, and redundancy and complexity increase a lot, while maintenability decreases
a lot too... The infernal spiral (direct french translation :-).
+ 
+ We can have a more elaborate approach to avoid all these drawbacks. I will try to explain
you this in the following lines.
+ 
+ = Architecture =
  http://www.bluexml.org/static/images/form-generation-dp.gif
  
-  * Form definition : describes a form from the fields it contains
+  * Form definition : describes the fields contained in the form
-  * Form binding : describes the xml object you want to obtain. According the framework you
use, you may convert it in Java object too for example
+  * Form binding : describes the xml object you want to obtain. According the framework you
use, you may convert it in Java object too, for example
-  * Form template : describes how you want your fields to be viewed
+  * Form template : describes how you want your fields to be displayed
  
-  * Form filtering (see FilteringDesignPattern) : filters the 3 files above thanks to additional
tags (the filters). This additional information may be useful after you read the current one.
+  * Filtering (see DesignPattern/Filtering) : filters and adapts files above thanks to additional
tags (the filters)
  
+ = Advanced concepts =
+ To avoid redundancy, increase maintenance and reduce complexity, it may be a good idea :
+  * to implement class concept (at the field level), that will be aggregated and will define
form repositories
+  * to define a metabind file for the binding and template file, associated with filter tags
(see DesignPattern/Filtering)
+  * to define meta widgets in this metabind file, that will aggregate binding and templating
tags in logical units you can reuse in different forms (like class for field and form definition)
+ 
+ Just before starting, here is the directory structure :
+ {{{
+ http://www.bluexml.org/static/images/class-form-generation-dp.gif
+ ||http://www.bluexml.org/static/images/doctype-form-generation-dp.gif
+ ||http://www.bluexml.org/static/images/metawidget-generation-dp.gif
+ }}}
+ == Class concept implementation ==
+ First, we have a form repository that lists the form classes we need. Form repositories
are stored in cud/doctypes directory. Above, we create a calendar doctype, composed of a few
classes :
+ {{{
+ <fd:form
+   xmlns:fd="http://apache.org/cocoon/forms/1.0#definition"
+   xmlns:fb="http://apache.org/cocoon/forms/1.0#binding"
+   xmlns:i18n="http://apache.org/cocoon/i18n/2.1"
+   xmlns:filter="http://bluexml.org/filter/1.0">
+ 
+   <fd:widgets id="calendar">
+ 	<fd:new id="Base"/>
+ 	<fd:new id="Authoring"/>
+ 	<fd:new id="Classification"/>
+ 	<fd:new id="Calendar"/>
+ 	<fd:new id="Date"/>
+ 	<fd:new id="Time"/>	
+ 	<fd:new id="Alarm"/>
+ 	<fd:new id="Security"/>	
+ 	<fd:new id="NewVersion"/>
+ 	<fd:new id="Versions"/>
+   </fd:widgets>
+ 
+ </fd:form>
+ }}}
+ Classes are in reality form definition. You will find above the form definition for the
Calendar class. You may notice dynamic list.
+ {{{
+ <fd:form xmlns:fd="http://apache.org/cocoon/forms/1.0#definition" 
+ 	xmlns:fb="http://apache.org/cocoon/forms/1.0#binding" 
+ 	xmlns:i18n="http://apache.org/cocoon/i18n/2.1" 
+ 	xmlns:filter="http://bluexml.org/filter/1.0">
+ 	
+ 	<fd:widgets>
+ 		<fd:class id="Calendar">
+ 			<fd:widgets>
+ 				<fd:field id="title" required="true">
+ 					<fd:datatype base="string"/>
+ 				</fd:field>
+ 				<fd:field id="description">
+ 					<fd:datatype base="string"/>
+ 				</fd:field>
+ 				<fd:field id="type">
+ 					<fd:datatype base="string"/>
+ 					<fd:selection-list src="cocoon:/process-selection-list" dynamic="true"/>
+ 				</fd:field>
+ 				<fd:field id="location">
+ 					<fd:datatype base="string"/>
+ 					<fd:selection-list src="cocoon:/process-selection-list-specific?xpath=/document[(meta/doctype='ae_entity')and(meta/type='lieu')]&amp;order=meta/name&amp;value=$doc/meta/id&amp;label=fn:string(fn:concat($doc/meta/name,%20'%20-%20',%20$doc/meta/city))"
dynamic="true"/>
+ 				</fd:field>
+ 				<fd:field id="link">
+ 					<fd:datatype base="string"/>
+ 				</fd:field>
+ 				<fd:field id="visibility">
+ 					<fd:datatype base="string"/>
+ 					<fd:selection-list src="cocoon:/process-selection-list" dynamic="true"/>
+ 				</fd:field>
+ 				<fd:field id="calendar">
+ 					<fd:datatype base="string"/>
+ 					<fd:selection-list src="cocoon:/process-selection-list" dynamic="true"/>
+ 				</fd:field>
+ 			</fd:widgets>
+ 		</fd:class>
+ 	</fd:widgets>
+ </fd:form>
+ }}}
+ With this first file, we'll have this final form definition.
+ 
+ == Form binding and template ==
+ I decided to mix binding and template because they are very tied. Structure and presentation
are often (but not always) related. Moreover, it reduces compexity and increases maintenability.
The use of meta widgets and filter tags help a lot to achieve this goal too. This way, one
file only is necessary. 
+ 
+ === Metawidgets ===
+ They are only a group of binding, template and filter tags.
+ 
+ For example, you maybe use often DateTime widgets, that displays date and time. To avoid
redundancy, you can define the following metawidget :
+ 
+ {{{
+ <?xml version="1.0" encoding="ISO-8859-1"?>
+ <!-- BX CPT -->
+ <fd:form
+     xmlns:fd="http://apache.org/cocoon/forms/1.0#definition" 
+ 	xmlns:fb="http://apache.org/cocoon/forms/1.0#binding" 
+ 	xmlns:i18n="http://apache.org/cocoon/i18n/2.1" 
+ 	xmlns:filter="http://bluexml.org/filter/1.0"
+ 	xmlns:meta="http://bluexml.org/meta/1.0">
+ 	
+     <meta:widget id="Time">
+         <meta:group label="Début" styling-style="width: 300px;" styling-layout="rowWithLabel">
+             <fb:value id="dtstart" path="dtstart">
+                 <fd:convertor datatype="date" type="formatting"/>
+             </fb:value>
+             <meta:group label="à" styling-layout="row">
+                 <fb:value id="tstart_hh" path="tstart_hh"/>h
+                 <fb:value id="tstart_mm" path="tstart_mm"/>m
+                 <fb:value id="tstart_ss" path="tstart_ss"/>s
+             </meta:group>
+          </meta:group>
+         <meta:group label="Fin" styling-style="width: 300px;" styling-layout="rowWithLabel">
+             <fb:value id="dtend" path="dtend">
+                 <fd:convertor datatype="date" type="formatting"/>
+             </fb:value>
+             <meta:group label="à" styling-layout="row">
+                 <fb:value id="tend_hh" path="tend_hh"/>h
+                 <fb:value id="tend_mm" path="tend_mm"/>m
+                 <fb:value id="tend_ss" path="tend_ss"/>s
+             </meta:group>
+         </meta:group>
+     </meta:widget>
+ 
+ </fd:form>
+ }}}
+ 
+ To include this set of definition (31 lines), you just have to put the following line in
your metabind file :
+ {{{
+     <meta:new id="DateTime"/>
+ }}}
+ 
+ === Metabind file ===
+ In the example below, a calendar doctype is defined. Usual bindings for DateTime (among
others) are reused through the DateTime metawidget.
+ 
+ {{{
+ <fb:context
+ 	xmlns:fd="http://apache.org/cocoon/forms/1.0#definition" 
+ 	xmlns:fb="http://apache.org/cocoon/forms/1.0#binding" 
+ 	xmlns:fi="http://apache.org/cocoon/forms/1.0#instance"
+ 	xmlns:ft="http://apache.org/cocoon/forms/1.0#template"
+ 	xmlns:filter="http://bluexml.org/filter/1.0"
+ 	xmlns:meta="http://bluexml.org/meta/1.0"
+ 	path="document">
+ 
+ 	<fb:context path="meta">
+         <meta:group 
+             styling-type="categories"
+             label="General"
+             state="internal-tab-state">
+ 
+             <meta:group styling-layout="columns" label="General">
+                 <meta:new id="General"/>
+                 <meta:new id="DateTime"/>
+             </meta:group>
+             <meta:group styling-type="fieldset" styling-layout="columns" label="Compl.">
+                 <fb:value id="visibility" path="visibility"/>
+                 <fb:value id="location" path="location"/>
+                 <fb:value id="link" path="link"/>
+             </meta:group>
+             <meta:new id="Alarm"/>            
+             <meta:new id="Classification"/>
+             <meta:new id="NewVersion"/>
+             <meta:new id="System"/>
+         </meta:group>
+ 	</fb:context>
+     <meta:new id="Versions"/>
+     <ft:widget id="action.ok"/>
+ </fb:context>
+ }}}
+ 
+ === Form binding ===
+ 
+ From this metabind file, we create the following form binding (by just changing the last
parameter) :
+  * [http://www.bluexml.org/crud-engine/form/cud/getMFM(BindingURI-atlanticevent-sysadmin-create)
create]
+  * [http://www.bluexml.org/crud-engine/form/cud/getMFM(BindingURI-atlanticevent-sysadmin-update)
update]
+  * [http://www.bluexml.org/crud-engine/form/cud/getMFM(BindingURI-atlanticevent-sysadmin-search)
search]
+ 
+ From this same metabind file, we may have different form binding for user's role (but it
is not configured here).
+ 
+ === Form template ===
+ 
+ From this metabind file, we create this form template (create, update, search).
+  * [http://www.bluexml.org/crud-engine/form/cud/getMFM(TemplateURI-atlanticevent-sysadmin-create)
create form template] - [http://www.bluexml.org/static/images/screenshot-form-sysadmin-create.gif
"real app's screenshot"]
+  * [http://www.bluexml.org/crud-engine/form/cud/getMFM(TemplateURI-atlanticevent-sysadmin-update)
update] - [http://www.bluexml.org/static/images/screenshot-form-sysadmin-update.gif "real
app's screenshot"]
+  * [http://www.bluexml.org/crud-engine/form/cud/getMFM(TemplateURI-atlanticevent-sysadmin-search)
search]  - [http://www.bluexml.org/static/images/screenshot-form-sysadmin-search.gif "real
app's screenshot"]
+ 
+ = Code =
+ Here is the global idea. All the code is part of the BlueXML project, located in http://www.bluexml.org.
Just download the code in the download section.
+ 
+ You may have a look through the cvs browser at :
+  * [http://www.bluexml.org/viewcvs/viewcvs.cgi/cms/src/blocks/core/crud-engine/webapp/feature/form/cud/
"cud directory feature"] - for sitemap, 
+  * [http://www.bluexml.org/viewcvs/viewcvs.cgi/cms/src/data/project/webapp/common/coplets/ged/cud/
"cud directory configuration"] - for common configuration files (other directories are for
specific data for each customer)
+ 
+ = Conclusion =
+ Here is the global idea.
+ Maybe we could implement this at the Forms framework core ?
+ 

Mime
View raw message