home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-cocoon-addon-1.4.9-installer.exe / forms.xml < prev    next >
Encoding:
Extensible Markup Language  |  2004-07-12  |  11.4 KB  |  289 lines

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--
  3.   Copyright 1999-2004 The Apache Software Foundation
  4.  
  5.   Licensed under the Apache License, Version 2.0 (the "License");
  6.   you may not use this file except in compliance with the License.
  7.   You may obtain a copy of the License at
  8.  
  9.       http://www.apache.org/licenses/LICENSE-2.0
  10.  
  11.   Unless required by applicable law or agreed to in writing, software
  12.   distributed under the License is distributed on an "AS IS" BASIS,
  13.   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.   See the License for the specific language governing permissions and
  15.   limitations under the License.
  16. -->
  17. <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "document-v10.dtd">
  18.  
  19. <document>
  20.  <header>
  21.   <title>Portal: Using forms</title>
  22.   <subtitle>Overview</subtitle>
  23.   <authors>
  24.    <person name="Carsten Ziegeler" email="cziegeler@apache.org"/>
  25.   </authors>
  26.  </header>
  27.  
  28.  <body>
  29.   <s1 title="Overview">
  30.    <p>This document gives an overview over how to use forms within the portal engine.
  31.    </p>
  32.    <p>
  33.      The sample portal that comes with the Cocoon distribution contains a working sample
  34.      for form handling. 
  35.    </p>
  36.   </s1>
  37.   <s1 title="Including Applications">
  38.     <p>
  39.      The portal allows to include a complete web application (with forms, links etc.)
  40.      that is build with Cocoon. Therefore it's possible to develop the forms
  41.      like you usually do with Cocoon without thinking about the portal. When you
  42.      are finished just include this application into the portal as a coplet.
  43.      The following shows you how to configure such an application as a coplet.
  44.     </p>
  45.     <p>
  46.       For including complete applications, the portal offers a specific coplet adapter,
  47.       the caching URI adapter. This is configured as the coplet base type: <em>CachingURICoplet</em>.
  48.       So each coplet you configure has to use this base type.
  49.     </p>
  50.     <p>
  51.       For each application you have to configure a coplet data object in the profile:
  52.     </p>
  53.     <source>
  54. <![CDATA[...
  55.    <coplet-data id="app-test-two" name="standard">
  56.       <title>Application Test</title>
  57.       <coplet-base-data>CachingURICoplet</coplet-base-data>
  58.       <attribute>
  59.           <name>buffer</name>
  60.           <value xsi:type="java:java.lang.Boolean" 
  61.                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  62.             true
  63.         </value>
  64.       </attribute>
  65.       <attribute>
  66.           <name>handleParameters</name>
  67.           <value xsi:type="java:java.lang.Boolean" 
  68.                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  69.              true
  70.         </value>
  71.       </attribute>
  72.       <attribute>
  73.           <name>uri</name>
  74.           <value xsi:type="java:java.lang.String" 
  75.                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  76.             cocoon:/coplets/html/application
  77.         </value>
  78.       </attribute>
  79.       <attribute>
  80.           <name>temporary:application-uri</name>
  81.           <value xsi:type="java:java.lang.String" 
  82.                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  83.             cocoon://samples/flow/jxcalc/
  84.         </value>
  85.       </attribute>
  86.    </coplet-data>
  87. ...]]>
  88.     </source>
  89.     <p>
  90.       As usual, the coplet data gets a unique id, a title and in this case the reference 
  91.       to the <em>CachingURICoplet</em>. In addition the <em>buffer</em> attribute is used
  92.       to buffer the output of the coplet which avoids broken responses in the case of a
  93.       malformed stream comming from the included application.
  94.     </p>
  95.     <p>
  96.       The <em>handleParameters</em> attribute has to be set to <em>true</em> as well, as 
  97.       the application has to handle it's own request parameters (for links or forms).
  98.     </p>
  99.     <p>
  100.       The <em>uri</em> attribute points to a Cocoon pipeline that will include your
  101.       application. This is not the pipeline of your application itself. The starting
  102.       URI for your application has to be configured using the attribute 
  103.       <em>temporary:application-uri</em>.
  104.     </p>
  105.     <p>
  106.       With this configuration you can configure instances of the coplet for each
  107.       user. In addition a user can have several instances of the same application.
  108.       If you look at the provided samples, you see two instances of a flow example
  109.       and two instances of a forms sample at the same time for each user.
  110.     </p>
  111.     <p>
  112.       However, if you allow several instances per user of the same application,
  113.       this application has to be developed with this aspect in mind. More about
  114.       this topic later on.
  115.     </p>
  116.     <p>
  117.       So, basically this is all you have to do. Develop your application standalone
  118.       without the example and include it as outlined above. You can for example
  119.       invoke the sample above (cocoon://samples/flow/jxcalc/) directly without the
  120.       portal.
  121.     </p>
  122.   </s1>
  123.   <s1 title="Building forms">
  124.     <p>
  125.       In this chapter we demonstrate using a sample how to build forms that can
  126.       be used within the portal. We will use Cocoon flow to define the logic for
  127.       the form, but for your own form you can of course use a different approach
  128.       as well. If you want to have complex forms, you can also use Cocoon forms
  129.       (Woody), but you have to be careful with correctly using JavaScript on
  130.       the client, which means you have to add the JavaScript to the response in
  131.       the main portal pipeline and not by the form itself. Or you avoid using
  132.       JavaScript on the client :)
  133.     </p>
  134.     <p>
  135.       As outlined in the previous chapter, you can define your form handling application
  136.       without taking care about the portal, so let's start developing it.
  137.     </p>
  138.     <s2 title="A Sample">
  139.       <p>
  140.         We will use flow for the logic. Each time the application is invoked, the same
  141.         URI is used; this URI calls a flow function. Inside this function we check
  142.         whether we have to display the form or a different (result) page.
  143.         So our sitemap looks like this:
  144.       </p>
  145.     <source>
  146. <![CDATA[...
  147.       <map:match pattern="form">
  148.         <map:call function="form"/>
  149.       </map:match>
  150. ...]]>
  151.     </source>
  152.       <p>
  153.         We have one single function in the flow, that checks if a session
  154.         attribute already contains a value or not. If no value is stored
  155.         in the session, this means that either the form has to be displayed
  156.         or the user just submitted some values. So we have to distinguish these
  157.         two cases as well:
  158.       </p>
  159.       <source>
  160. <![CDATA[...
  161. function form() {
  162.     // is the value stored in the session?
  163.     if ( cocoon.session.getAttribute("form") == null ) {
  164.         // No: is this a submit?
  165.         var name = cocoon.request.getParameter("name");
  166.         if ( name == null ) {
  167.             // No: display the form
  168.             cocoon.sendPage("page/form", {});
  169.         } else {
  170.             // It's a submit, so process the value
  171.             cocoon.session.setAttribute("form", name);
  172.             cocoon.sendPage("page/received", {"name" : name});         
  173.         }
  174.     } else {
  175.         // just display the value
  176.         var name = cocoon.session.getAttribute("form");
  177.         cocoon.sendPage("page/content", {"name" : name});         
  178.     }
  179. }...]]>
  180.       </source>
  181.       <p>
  182.         This schema allows to use the same pipeline for all purposes. However,
  183.         if you want a different design, you could e.g. use a different pipeline
  184.         for processing the form data etc.
  185.       </p>
  186.       <p>
  187.         In each case, the view is called which is a Cocoon pipeline. For
  188.         example the pipeline for the form reads an XML document that looks like
  189.         this:
  190.       </p>
  191.       <source>
  192. <![CDATA[...
  193. <page>
  194.     <title>Form</title>
  195.     <content>
  196.       <form method="post" action="form">
  197.         <para>Please enter your <strong>name</strong>: <input type="text" name="name"/></para>
  198.         <input type="submit" name="submit" value="Enter"/>
  199.       </form>
  200.     </content>
  201. </page>
  202. }...]]>
  203.       </source>
  204.       <p>
  205.         As already pointed out, you develop your application like you would do without
  206.         the portal. Note in the sample above that the target of the form is the
  207.         <em>form</em> pipeline, containing the call to the flow.
  208.       </p>
  209.       <p>
  210.         So, how does this work? Each link (or target of a form action) is rewritten
  211.         by the portal engine. The link is transformed into an event. When now the
  212.         user activates such a link (or form) the event is send to the portal and
  213.         the portal updates the URI to call for the portlet. The <em>portal-html-eventlink</em>
  214.         transformer does the rewriting of all links and forms in combination
  215.         with the <em>portal-coplet</em> transformer that is one of the last
  216.         transformers in the main portal pipeline.
  217.       </p>
  218.       <p>
  219.         Each application portlet that isn't changed during this single request/response
  220.         cycle, isn't "activated" which means the corresponding application pipeline
  221.         is not called.
  222.       </p>
  223.       <p>
  224.         The portal caches the response of an application and serves the coplet out
  225.         of the cache until an action for this coplet is triggered.
  226.       </p>
  227.     </s2>
  228.     <s2 title="Several instances of an application">
  229.       <p>
  230.         If you allow the user to have several instances of the same application,
  231.         the application has to be aware of this fact. Imagine that each instance
  232.         should have its own data set, but as the user is the same, the session
  233.         is shared by the instances. So, a unique identifier for each instance
  234.         is required.
  235.       </p>
  236.       <p>
  237.         The portal framework already supplies this identifier and passes it
  238.         as a request parameter to the pipeline of your application. The name
  239.         of the parameter is <em>copletid</em> and the value is the unique id.
  240.         In our sample, we pass this identifier to the flow script using an
  241.         input module:
  242.       </p>
  243.       <source>
  244. <![CDATA[...
  245.       <map:match pattern="form">
  246.         <map:call function="form">
  247.           <map:parameter name="copletId" value="{request-param:copletid}"/>
  248.         </map:call>
  249.       </map:match>
  250. ...]]>
  251.       </source>
  252.       <p>
  253.         In the flow script, we can now use this identifier to calculate a unique
  254.         session key to store the information:
  255.       </p>
  256.       <source>
  257.     // get the coplet id
  258.     var cid = cocoon.parameters["copletId"];
  259.     var key = cid + "/myform";
  260.       </source>
  261.       <p>
  262.         From now on you can use this key to get/store session attributes etc. In
  263.         addition you can use all features available to flow, like looking up
  264.         components and using them.
  265.       </p>
  266.     </s2>
  267.     <s2 title="Extending the Sample">
  268.       <p>
  269.         Although the sample is very simple (or more precisly the form is very simple)
  270.         it demonstrates a possible way to build coplets that handle forms. You can
  271.         use this as a guideline for your own forms.
  272.       </p>
  273.       <p>
  274.         If you need, e.g. validation of the form, you can simply add the validation
  275.         in the flow script and return a corresponding view in the case of a
  276.         validation error. If you need a more complex processing, e.g. sending an
  277.         email, you can simply add this in the flow script as well. Or you can
  278.         code the logic into a Java class and call this class from the flow script.
  279.       </p>
  280.       <p>
  281.         In addition, you can use Cocoon forms with all the nice features (widgets,
  282.         validation, binding etc.) as well. You only have to provide a working set
  283.         of stylesheets that work in the portal.
  284.       </p>
  285.     </s2>
  286.   </s1>
  287.  </body>
  288. </document>
  289.