Dear Wiki user,

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

The following page has been changed by CedricDumoulin:
http://wiki.apache.org/shale/ShaleAndClayTutorial

The comment on the change is:
Format code

------------------------------------------------------------------------------
  
  Create a directory where you want the project, ex.  C:\My 
projects\Shale``Clay. Open a shell (CMD) and type in (on one line):
  
+ {{{
- mvn archetype:create -D``archetypeGroupId=org.apache.shale.clay 
-D``archetypeArtifactId=clay-starter-archetype 
-D``archetypeVersion=1.0-SNAPSHOT -D``groupId=com.acme.test 
-D``packageName=com.acme.test -D``artifactId=shaleclay
+ mvn archetype:create -DarchetypeGroupId=org.apache.shale.clay 
-DarchetypeArtifactId=clay-starter-archetype -DarchetypeVersion=1.0-SNAPSHOT 
-DgroupId=com.acme.test -DpackageName=com.acme.test -DartifactId=shaleclay
- 
+ }}}
  What happens here is that Maven will create a project based on Shale and 
Clay. The parameters are:
  
- * archetype``Group``Id –  The archetype groupId[[BR]]
+  * archetype``Group``Id –  The archetype groupId
- * archetype``Artifact``Id – The archetype artifactId[[BR]]
+  * archetype``Artifact``Id – The archetype artifactId
- * archetype``Version – The archetype version number[[BR]]
+  * archetype``Version – The archetype version number
- * group``Id – The groupId of you project[[BR]]
+  * group``Id – The groupId of you project
- * package``Name – The default package name of  your project – included 
source is placed here[[BR]]
+  * package``Name – The default package name of  your project – included 
source is placed here
- * artifact``Id - The groupId of you project[[BR]]
+  * artifact``Id - The groupId of you project
  
  After you have done his, a project will have been created for you in a 
directory with the same name as you gave for the artifactId. Move to this 
directory.
  
@@ -81, +82 @@

  In the Java sourcefolder (src/main/java) under the packagename you provided 
you should find two classes:
  Person and TestVC. 
  
- In the resources folder (src/main/resources) you will find three property 
files. This is actually one property file with two language provisions of it. 
These can be identified by their nameextention.
+ In the resources folder (src/main/resources) you will find three property 
files. This is actually one property file with two language provisions of it. 
These can be identified by their name extention.
   
  In the web sources folder (src/main/webapp) you will find several folders:
  
- The folder ”images” contains the images and backgrounds that are used for 
the site.
+  * The folder ”images” contains the images and backgrounds that are used 
for the site.
- 
- The folder ”pages” contains standard definitions (defaultxxx.html) of the 
various parts that make up the site, along with some specific definitions 
(pageXbody.html)
+  * The folder ”pages” contains standard definitions (defaultxxx.html) of 
the various parts that make up the site, along with some specific definitions 
(pageXbody.html)
- 
- The folder “templates” contains the template that we are using to build 
our site – we will return to this shortly 
+  * The folder “templates” contains the template that we are using to 
build our site – we will return to this shortly 
- 
- The folder ”theme” contains the cascading stylesheet we use to format our 
site.
+  * The folder ”theme” contains the cascading stylesheet we use to format 
our site.
- 
- In the folder ”WEB-INF” we find all the important configurationfiles.
+  * In the folder ”WEB-INF” we find all the important configuration files.
  
  attachment:ShaleClay8.jpg
  
  Lets take a closer look at these, starting with web.xml where we find these 
important declarations:
  
+ {{{
-    <!-- Override the default suffix for extension-mapped -->[[BR]]
+    <!-- Override the default suffix for extension-mapped -->
-    <context-param>[[BR]]
+    <context-param>
-       <param-name>javax.faces.DEFAULT_SUFFIX</param-name>[[BR]]
+       <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
-       <param-value>.jsf</param-value>[[BR]]
+       <param-value>.jsf</param-value>
-    </context-param>[[BR]]
+    </context-param>
  
-    <!-- Select JSF State Saving Mode -->[[BR]]
+    <!-- Select JSF State Saving Mode -->
-    <context-param>[[BR]]
+    <context-param>
-       <param-name>javax.faces.STATE_SAVING_METHOD</param-name>[[BR]]
+       <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
-       <param-value>client</param-value>[[BR]]
+       <param-value>client</param-value>
-    </context-param>[[BR]]
+    </context-param>
  
-    <!-- Clay Common Configuration Resources -->[[BR]]
+    <!-- Clay Common Configuration Resources -->
-    <context-param>[[BR]]
+    <context-param>
-       <param-name>[[BR]]
+       <param-name>
-          org.apache.shale.clay.COMMON_CONFIG_FILES[[BR]]
+          org.apache.shale.clay.COMMON_CONFIG_FILES
-       </param-name>[[BR]]
+       </param-name>
-       <param-value>/WEB-INF/clay-config.xml</param-value>[[BR]]
+       <param-value>/WEB-INF/clay-config.xml</param-value>
-    </context-param>[[BR]]
+    </context-param>
  
-    <!-- Clay Configuration Full XML view Resources -->[[BR]]
+    <!-- Clay Configuration Full XML view Resources -->
-    <context-param>[[BR]]
+    <context-param>
-       <param-name>[[BR]]
+       <param-name>
-          org.apache.shale.clay.FULLXML_CONFIG_FILES[[BR]]
+          org.apache.shale.clay.FULLXML_CONFIG_FILES
-       </param-name>[[BR]]
+       </param-name>
-       <param-value>/WEB-INF/clay-views-config.xml</param-value>[[BR]]
+       <param-value>/WEB-INF/clay-views-config.xml</param-value>
-    </context-param>[[BR]]
+    </context-param>
  
-    <!-- Clay XML View Suffix -->[[BR]]
+    <!-- Clay XML View Suffix -->
-    <context-param>[[BR]]
+    <context-param>
-       <param-name>[[BR]]
+       <param-name>
-          org.apache.shale.clay.XML_TEMPLATE_SUFFIX[[BR]]
+          org.apache.shale.clay.XML_TEMPLATE_SUFFIX
-       </param-name>[[BR]]
+       </param-name>
-       <param-value>.jsf</param-value>[[BR]]
+       <param-value>.jsf</param-value>
-    </context-param>[[BR]]
+    </context-param>
- 
+ }}}
  These declarations (context-param) are used by Clay and the Java``Server 
Faces (JSF) implementation at startup.
  
- * javax.faces.DEFAULT_SUFFIX – Tells which page suffixes should be handled 
by JSF[[BR]]
+  * javax.faces.DEFAULT_SUFFIX – Tells which page suffixes should be handled 
by JSF
- * javax.faces.STATE_SAVING_METHOD – How should session state be persisted 
(Client-side or Server-side)[[BR]]
+  * javax.faces.STATE_SAVING_METHOD – How should session state be persisted 
(Client-side or Server-side)
- * org.apache.shale.clay.COMMON_CONFIG_FILES – What are the name(s )of the 
Clay configuration file(s),  providing absolute path within the 
web-context[[BR]]
+  * org.apache.shale.clay.COMMON_CONFIG_FILES – What are the name(s )of the 
Clay configuration file(s),  providing absolute path within the web-context
- * org.apache.shale.clay.FULLXML_CONFIG_FILES – What are the name(s) of the 
Clay configuration file(s) that tells Clay about our page definitions.[[BR]]
+  * org.apache.shale.clay.FULLXML_CONFIG_FILES – What are the name(s) of the 
Clay configuration file(s) that tells Clay about our page definitions.
- * org.apache.shale.clay.XML_TEMPLATE_SUFFIX – Which page suffixes should be 
handled by Clay.[[BR]]
+  * org.apache.shale.clay.XML_TEMPLATE_SUFFIX – Which page suffixes should 
be handled by Clay.
  
  Then are the Filter definitions. A filter is a Javaclass that will be called 
by the webcontainer on every request that comes into it (Actually only requests 
that match a certain predefined pattern – See filter-mapping below)
  
+ {{{
-    <filter>[[BR]]
+    <filter>
-       <filter-name>shale</filter-name>[[BR]]
+       <filter-name>shale</filter-name>
-       <filter-class>[[BR]]
+       <filter-class>
-          org.apache.shale.application.faces.Shale``Application``Filter[[BR]]
+          org.apache.shale.application.faces.ShaleApplicationFilter
-       </filter-class>[[BR]]
+       </filter-class>
-    </filter>[[BR]]
+    </filter>
  
-    <!-- Shale Application Controller Filter Mapping -->[[BR]]
+    <!-- Shale Application Controller Filter Mapping -->
-    <filter-mapping>[[BR]]
+    <filter-mapping>
-    <filter-name>shale</filter-name>[[BR]]
+    <filter-name>shale</filter-name>
-    <url-pattern>/*</url-pattern>[[BR]]
+    <url-pattern>/*</url-pattern>
-    </filter-mapping>[[BR]]
+    </filter-mapping>
+ }}}
  
  Here Shale is wired into the request processing. In this case the Shale 
filter will be invoked on every request because of the /* pattern.
  
  Next comes the Servlet definitions. These servlets are instandiated by the 
webcontainer at startup because they have a load-on-startup set. These Servlets 
are responsible for setting up various session and application scoped 
parameters based on the configuration files, and also for receiving all 
requests (That match a pattern) that comes into the webapplication
  
+ {{{
-    <!-- Java``Server Faces Servlet Configuration --> [[BR]]
+    <!-- JavaServer Faces Servlet Configuration --> 
-    <servlet> [[BR]]
+    <servlet> 
-       <servlet-name>faces</servlet-name> [[BR]]
+       <servlet-name>faces</servlet-name> 
-       <servlet-class>javax.faces.webapp.Faces``Servlet</servlet-class> [[BR]]
+       <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
-       <load-on-startup>1</load-on-startup> [[BR]]
+       <load-on-startup>1</load-on-startup> 
-    </servlet> [[BR]]
+    </servlet> 
  
-    <!-- Java``Server Faces Servlet Mapping --> [[BR]]
+    <!-- Java``Server Faces Servlet Mapping --> 
-    <servlet-mapping> [[BR]]
+    <servlet-mapping> 
-       <servlet-name>faces</servlet-name> [[BR]]
+       <servlet-name>faces</servlet-name> 
-       <url-pattern>*.jsf</url-pattern> [[BR]]
+       <url-pattern>*.jsf</url-pattern> 
-    </servlet-mapping> [[BR]]
+    </servlet-mapping> 
+ }}}
  
  Here the JSF Servlet is defined. It will be the handler of all requests that 
end with .jsf
  
  Finally we tell the webcontainer how to handle our pages going back to the 
client. Since .jsf is not a well known mime-type, we need to inform the client 
that it should handle it as text/html.
  
+ {{{
-       <mime-mapping>[[BR]]
+       <mime-mapping>
-               <extension>jsf</extension>[[BR]]
+               <extension>jsf</extension>
-               <mime-type>text/html</mime-type>[[BR]]
+               <mime-type>text/html</mime-type>
-       </mime-mapping>[[BR]]
+       </mime-mapping>
+ }}}
  
  The next file we look at is the faces-config.xml file. This file governs the 
setup of JSF. It is normally divided into three sections
  
- * General information - application [[BR]]
+  * General information - application 
- * Navigation rules - navigation-rule[[BR]]
+  * Navigation rules - navigation-rule
- * Managed beans - managed-bean[[BR]]
+  * Managed beans - managed-bean
  
  First in out file we define which languages this application supports; 
Norwegian(no) and English(en), and that the default is English.
  
@@ -206, +210 @@

  
  The section that the page is divided into are:
  
-    * Pagetitle[[BR]]
+    * Pagetitle
-    * Leftmenu[[BR]]
+    * Leftmenu
-    * Content[[BR]]
+    * Content
-    * Footer[[BR]]
+    * Footer
  
- <body>[[BR]]
+ {{{
+ <body>
-       <div id="head"><span jsfid="clay" clayjsfid="@headerContent"[[BR]]
+       <div id="head"><span jsfid="clay" clayjsfid="@headerContent"
-               allowbody="false">Header Content</span></div>[[BR]]
+               allowbody="false">Header Content</span></div>
-       <div id='logo'>&nbsp;</div>[[BR]]
+       <div id='logo'>&nbsp;</div>
-       <div id="left">&nbsp;</div>[[BR]]
+       <div id="left">&nbsp;</div>
-       <div id="menu"><span jsfid="clay" clayjsfid="@leftContent"[[BR]]
+       <div id="menu"><span jsfid="clay" clayjsfid="@leftContent"
-               allowbody="false">Left Content</span></div>[[BR]]
+               allowbody="false">Left Content</span></div>
-       <div id="pad1">&nbsp;</div>[[BR]]
+       <div id="pad1">&nbsp;</div>
-       <div id='content'><span jsfid="clay" clayjsfid="@bodyContent"[[BR]]
+       <div id='content'><span jsfid="clay" clayjsfid="@bodyContent"
-               allowbody="false">Body Content</span></div>[[BR]]
+               allowbody="false">Body Content</span></div>
-       <div id="pad1">&nbsp;</div>[[BR]]
+       <div id="pad1">&nbsp;</div>
-       <div id="footer"><span jsfid="clay" clayjsfid="@footerContent"[[BR]]
+       <div id="footer"><span jsfid="clay" clayjsfid="@footerContent"
-               allowbody="false">Footer Content</span></div>[[BR]]
+               allowbody="false">Footer Content</span></div>
- </body>[[BR]]
+ </body>
+ }}}
  
  These sections are identifiable with the help of the attribute 
”clayjsfid” on the <SPAN> tags. Here we see that we have: @headerContent, 
@leftContent. @bodyContent and @footerContent. These are what we refer to as 
symbols in Clay. This means that Clay processes the page looking for symbols 
and replaces them with their counterpart efinition in the configuration 
file(s). Lets look at how this template is defined as a Clay component in the 
clay-config.xml file:
  
+ {{{
-       <component jsfid="baseLayout" extends="clay" id="base">[[BR]]
+       <component jsfid="baseLayout" extends="clay" id="base">
-               <attributes>[[BR]]
+               <attributes>
-                       <set name="clayJsfid" value="/templates/standard.html" 
/>[[BR]]
+                       <set name="clayJsfid" value="/templates/standard.html" 
/>
-               </attributes>[[BR]]
+               </attributes>
-               <symbols>[[BR]]
+               <symbols>
-                       <set name="title" value="Hello World" />[[BR]]
+                       <set name="title" value="Hello World" />
-                       <set name="leftContent" 
value="/pages/defaultLeftNav.html" />[[BR]]
+                       <set name="leftContent" 
value="/pages/defaultLeftNav.html" />
-                       <set name="headerContent" 
value="/pages/defaultHeader.html" />[[BR]]
+                       <set name="headerContent" 
value="/pages/defaultHeader.html" />
-                       <set name="bodyContent" value="/pages/defaultBody.html" 
/>[[BR]]
+                       <set name="bodyContent" value="/pages/defaultBody.html" 
/>
-                       <set name="footerContent" 
value="/pages/defaultFooter.html" />[[BR]]
+                       <set name="footerContent" 
value="/pages/defaultFooter.html" />
-               </symbols>[[BR]]
+               </symbols>
-       </component>[[BR]]
+       </component>
+ }}}
  
  As we can see we have a section named “symbols”, Here we instruct Clay 
what to substitute the symbols with. In this case we have made some defaults to 
substitute in and the will be used unless we override them when defining a 
specific page. Now that we have a template to work with the work of creating 
specific pages start. Since we for now only want to replace the content part 
(defined by the symbol bodyContent) and the page title, we only need to create 
those parts. We now need to let Clay know about these. To tell Clay how to 
build our specifi pages we do that in the clay-views.xml file. If we open this 
file, we will find several page definitions:
  
+ {{{
-       <component jsfid="/page1.jsf" extends="baseLayout">[[BR]]
+       <component jsfid="/page1.jsf" extends="baseLayout">
-               <symbols>[[BR]]
+               <symbols>
-                       <set name="title" value="Page 1" />[[BR]]
+                       <set name="title" value="Page 1" />
-                       <set name="bodyContent" value="/pages/page1Body.html" 
/>[[BR]]
+                       <set name="bodyContent" value="/pages/page1Body.html" />
-               </symbols>[[BR]]
+               </symbols>
        </component>
-       <component jsfid="/page2.jsf" extends="baseLayout">[[BR]]
+       <component jsfid="/page2.jsf" extends="baseLayout">
-               <symbols>[[BR]]
+               <symbols>
-                       <set name="title" value="Page 2" />[[BR]]
+                       <set name="title" value="Page 2" />
-                       <set name="bodyContent" value="/pages/page2Body.html" 
/>[[BR]]
+                       <set name="bodyContent" value="/pages/page2Body.html" />
-               </symbols>[[BR]]
+               </symbols>
        </component>
-       <component jsfid="/page3.jsf" extends="baseLayout">[[BR]]
+       <component jsfid="/page3.jsf" extends="baseLayout">
-               <symbols>[[BR]]
+               <symbols>[
-                       <set name="title" value="Page 3" />[[BR]]
+                       <set name="title" value="Page 3" />
-                       <set name="bodyContent" value="/pages/page3Body.html" 
/>[[BR]]
+                       <set name="bodyContent" value="/pages/page3Body.html" />
-               </symbols>[[BR]]
+               </symbols>
-       </component>[[BR]]
+       </component>
+ }}}
  
  Here we define 3 components that inherit from our basecomponent 
“baseLayout”. As we mentioned we override the definitions of the title and 
bodyContent. We have now created 3 components based on a common template, but 
where the title and content vary. If we now look at for instance page1Body.html:
  
- <h3>[[BR]]
+ {{{
+ <h3>
-     <span jsfid="outputText" value="#{messages['content.title.page1']}" 
allowBody="false">Clay template application - Page 1</span>[[BR]]
+     <span jsfid="outputText" value="#{messages['content.title.page1']}" 
allowBody="false">Clay template application - Page 1</span>
- </h3>[[BR]]
- <p>[[BR]]
+ </h3>
+ <p>
-     <span jsfid="outputText" value="#{messages['content.message.page1']}" 
allowBody="false">This is Page 1 content</span>[[BR]]
+     <span jsfid="outputText" value="#{messages['content.message.page1']}" 
allowBody="false">This is Page 1 content</span>
- </p>[[BR]] 
+ </p>
+ }}}
  
  then we see that we refer to the jsfid ”outputText”. This is one of the 
standard predefined Clay components that we can utilize. It’s purpose is to 
output text. Further we refer to “#{messages['content.message.page1']}. This 
is a reference to a ”managed-bean” named messages. This is a bean that 
Shale will instantiate for us, If you open the faces-config.xml file you will 
find this at the bottom:
  
+ {{{
-       <!-- Make resources available to the pages by defining it here (in a 
page use messages['propertyname'] as value -->[[BR]]
+       <!-- Make resources available to the pages by defining it here (in a 
page use messages['propertyname'] as value -->
-       <managed-bean>[[BR]]
+       <managed-bean>
-               <managed-bean-name>messages</managed-bean-name>[[BR]]
+               <managed-bean-name>messages</managed-bean-name>
-               <managed-bean-class>[[BR]]
+               <managed-bean-class>
-                       org.apache.shale.util.Load``Bundle[[BR]]
+                       org.apache.shale.util.LoadBundle
-               </managed-bean-class>[[BR]]
+               </managed-bean-class>
-               <managed-bean-scope>application</managed-bean-scope>[[BR]]
+               <managed-bean-scope>application</managed-bean-scope>
-               <managed-property>[[BR]]
+               <managed-property>
-                       <property-name>basename</property-name>[[BR]]
+                       <property-name>basename</property-name>
-                       <value>[[BR]]
+                       <value>
-                               Resource``Bundle[[BR]]
+                               ResourceBundle
-                       </value>[[BR]]
+                       </value>
-               </managed-property>[[BR]]
+               </managed-property>
-       </managed-bean>[[BR]]
+       </managed-bean>
+ }}}
  
  Here we define the messages bean. In the this case it is a special purpose 
Shale bean. It purpose it to make available to us a resourcebundle that we have 
created. The name of that is Resource``Bundle.properties. You will find it the 
folder src/main/resources. This bean is available application wide (given by 
the scope section). It supports internationalization (I18N), so we can have 
several versions of the file where the are unique by their extension (_en, _no 
etc.).
  
@@ -294, +308 @@

  
  If we more on and look at the second page (/page2.jsf) and its content 
(pageBody2.html) we see that we have used more of Clays functionalities.
  
- <h3>[[BR]]
+ {{{
+ <h3>
-     <span jsfid="outputText" value="#{messages['content.title.page2']}" 
allowBody="false">Clay template application - Page 2</span>[[BR]]
+     <span jsfid="outputText" value="#{messages['content.title.page2']}" 
allowBody="false">Clay template application - Page 2</span>
- </h3>[[BR]]
- <p>[[BR]]
+ </h3>
+ <p>
-     <span jsfid="outputText" value="#{messages['content.message.page2']}" 
allowBody="false">This is Page 2 content</span>[[BR]]
+     <span jsfid="outputText" value="#{messages['content.message.page2']}" 
allowBody="false">This is Page 2 content</span>
- </p>[[BR]]
+ </p>
- <span jsfid="form">[[BR]]
+ <span jsfid="form">
-     <table>[[BR]]
+     <table>
-         <tbody>[[BR]]
+         <tbody>
-             <tr>[[BR]]
+             <tr>
-               <th>[[BR]]
+               <th>
-                   <span jsfid="outputText" value="#{messages['name.label']}" 
allowBody="false">Please enter your name</span>[[BR]]
+                   <span jsfid="outputText" value="#{messages['name.label']}" 
allowBody="false">Please enter your name</span>
-                 </th>[[BR]]
+                 </th>
-                 <td>[[BR]]
+                 <td>
-                     <input id="name" type="text" size="40" maxlength="50" 
value="[EMAIL PROTECTED]"/>[[BR]]
+                     <input id="name" type="text" size="40" maxlength="50" 
value="[EMAIL PROTECTED]"/>
-                 </td>[[BR]]
+                 </td>
-             </tr>[[BR]]
+             </tr>
-             <tr>[[BR]]
+             <tr>
-                 <td colspan="2">[[BR]]
+                 <td colspan="2">
-                     <input type="submit" action="[EMAIL PROTECTED]" 
value="#{messages['page2.button.label']}">[[BR]]
+                     <input type="submit" action="[EMAIL PROTECTED]" 
value="#{messages['page2.button.label']}">
-                 </td>[[BR]]
+                 </td>
-             </tr>[[BR]]
+             </tr>
-         </tbody>[[BR]]
+         </tbody>
-     </table>[[BR]]
+     </table>
- </span>[[BR]]
+ </span>
+ }}}
  
  Here we see that we no longer only use the SPAN convenience tag, but the 
INPUT tag instead. Clay has 11 implicitly mapped tags. Those are html tags that 
it will check to see if they have been annotated with Clay attributes:
  
  
-    1.   <a> </a>[[BR]]
+    1.   <a> </a>
-    2.  <form> </form>[[BR]]
+    2.  <form> </form>
-    3.  <input type=text>[[BR]]
+    3.  <input type=txt>
-    4.  <input type=checkbox>[[BR]]
+    4.  <input type=checkbox>
-    5.  <input type=radio>[[BR]]
+    5.  <input type=radio>
-    6.  <input type=submit>[[BR]]
+    6.  <input type=submit>
-    7.  <label> </label>[[BR]]
+    7.  <label> </label>
-    8.  <select> </select>[[BR]]
+    8.  <select> </select>
-    9.  <select multiple> </select>[[BR]]
+    9.  <select multiple> </select>
-   10.  <option>[[BR]]
+   10.  <option>
-   11.  <textarea> </textarea>[[BR]]
+   11.  <textarea> </textarea>
  
  This means that one can use these tags and add the Clay specifi attributes. 
Another thing to notice is that we have added a new symbol: @managed-bean-name. 
This symbol has special meaning in Shale/Clay. If we go back and look at the 
faces-config.xml file again, we will find the following declaration:
  
+ {{{
-       <!-- Backing bean for page1 -->[[BR]]
+       <!-- Backing bean for page1 -->
-       <managed-bean id="page1">[[BR]]
+       <managed-bean id="page1">
-               <managed-bean-name>page2</managed-bean-name>[[BR]]
+               <managed-bean-name>page2</managed-bean-name>
-               <managed-bean-class>[[BR]]
+               <managed-bean-class>
-                       com com.acme.test.TestVC [[BR]]
+                       com com.acme.test.TestVC
-               </managed-bean-class>[[BR]]
+               </managed-bean-class>
-               <managed-bean-scope>request</managed-bean-scope>[[BR]]
+               <managed-bean-scope>request</managed-bean-scope>
-       </managed-bean>[[BR]]
+       </managed-bean>
-       <managed-bean id="page2">[[BR]]
+       <managed-bean id="page2">
-               <managed-bean-name>page2</managed-bean-name>[[BR]]
+               <managed-bean-name>page2</managed-bean-name>
-               <managed-bean-class>[[BR]]
+               <managed-bean-class>
-                       com.acme.test.TestVC[[BR]]
+                       com.acme.test.TestVC
-               </managed-bean-class>[[BR]]
+               </managed-bean-class>
-               <managed-bean-scope>request</managed-bean-scope>[[BR]]
+               <managed-bean-scope>request</managed-bean-scope>
-               <managed-property>[[BR]]
+               <managed-property>
-                       <property-name>person</property-name>[[BR]]
+                       <property-name>person</property-name>
-                       <property-class>[[BR]]
+                       <property-class>
-                               com.acme.test.Person[[BR]]
+                               com.acme.test.Person
-                       </property-class>[[BR]]
+                       </property-class>
-                       <value>#{person}</value>[[BR]]
+                       <value>#{person}</value>
-               </managed-property>[[BR]]
+               </managed-property>
-       </managed-bean>[[BR]]
+       </managed-bean>
+ }}}
  
  What we do here is to define what is known as a backing beans or managed 
beans. These are beans that Shale will make available to us. Shale uses an 
implicit mapping strategy to decide which beans it should instantiate for a 
given view. If our page is called page1, it will then look for a managed bean 
with the same name and instantiate it. If you have a path to your page that 
spans several folders as in /foo/bar/pages/page1 then you need to define it as 
foo$bar$pages$page1 for Shale to find it and associate it with the page.
  
@@ -366, +384 @@

  
  Lets take a closer look at the bean (com.acme.test.TestVC) that we are using 
for our backing bean. The first thing we notice is that it inherits from  
[http://shale.apache.org/shale-view AbstractViewController]. This class gives 
us some hooks (callbacks) into some Shale added lifecycle methods so that we 
can perform certain tasks that are relevant to that particular lifecycle. The 
next thing to notice is that is refers to a class Person. If you look in the 
faces-config.xml file again you will find the following declaration:
  
+ {{{
-       <managed-bean id="person">[[BR]]
+       <managed-bean id="person">
-               <managed-bean-name>person</managed-bean-name>[[BR]]
+               <managed-bean-name>person</managed-bean-name>
-               <managed-bean-class>[[BR]]
+               <managed-bean-class>
-                       com.acme.test.Person[[BR]]
+                       com.acme.test.Person
-               </managed-bean-class>[[BR]]
+               </managed-bean-class>
-               <managed-bean-scope>session</managed-bean-scope>[[BR]]
+               <managed-bean-scope>session</managed-bean-scope>
-       </managed-bean>[[BR]]
+       </managed-bean>
+ }}}
  
  If you look at the above definition you will see that Person has been 
declared as a managed bean. Because Person is defined as a managed bean, Shale 
will inject it into our page2 definition because we instructed it to through 
the use of the managed-property section. Since Person has a scope of session it 
will be persisted between request so that any value that we set on one request 
will be available on the next. Finally we see that we define a method sayHello 
on the TestVC bean, and that we refer to that method in the page2Body.html in 
the “action“ attribute (: [EMAIL PROTECTED]).
  
@@ -382, +402 @@

  
  When we do a post against the server JSF/Shale will populate all fields in 
the managed bean that we have associated with fields on the page (There is a 
lot of other things going on too but that is beyond the scope of this 
tutorial). That means that when the method sayHello is invoked a bean Person 
will have been instantiated and filled with the values coming from our page. In 
the method sayHello we do not actually do anything other that return a string. 
This string is used by JSF to figure out which view it should render. This is 
also defined in the faces-config.xml file under the navigation rules section.
  
- 
+ {{{
-       <navigation-rule>[[BR]]
+       <navigation-rule>
-               <!-- These pages should be accessable form everywhere -->[[BR]]
+               <!-- These pages should be accessable form everywhere -->
-               <from-view-id>*</from-view-id>[[BR]]
+               <from-view-id>*</from-view-id>
-               <navigation-case>[[BR]]
+               <navigation-case>
-                       <from-outcome>home</from-outcome>[[BR]]
+                       <from-outcome>home</from-outcome>
-                       <to-view-id>/page1.jsf</to-view-id>[[BR]]
+                       <to-view-id>/page1.jsf</to-view-id>
-               </navigation-case>[[BR]]
+               </navigation-case>
-               <navigation-case>[[BR]]
+               <navigation-case>
-                       <from-outcome>page2</from-outcome>[[BR]]
+                       <from-outcome>page2</from-outcome>
-                       <to-view-id>/page2.jsf</to-view-id>[[BR]]
+                       <to-view-id>/page2.jsf</to-view-id>
-               </navigation-case>[[BR]]
+               </navigation-case>
-               <navigation-case>[[BR]]
+               <navigation-case>
-                       <from-outcome>page3</from-outcome>[[BR]]
+                       <from-outcome>page3</from-outcome>
-                       <to-view-id>/page3.jsf</to-view-id>[[BR]]
+                       <to-view-id>/page3.jsf</to-view-id>
-               </navigation-case>[[BR]]
+               </navigation-case>
-       </navigation-rule>[[BR]]
+       </navigation-rule>
+ }}}
  
  In TestVC.sayHello we returned the string page3, and in the navigation rules 
we see  that this will send us to /page3.jsf. You can define many navigation 
rules, and also note that a navigation rule always must have a from view. If 
you use the asterix (*) then that will mean that unless otherwise specified the 
outcomes become global rules.
  
  As a result of our action page3 will be rendered. If we look at the 
bodyCOntent definition for page3 in the clay-views-config.xml file we will se 
that it refers to page3Body.html.
  
- <h3>[[BR]]
+ {{{
+ <h3>
-     <span jsfid="outputText" value="#{messages['content.title.page3']}" 
allowBody="false">Clay template application - Page 3</span>[[BR]]
+     <span jsfid="outputText" value="#{messages['content.title.page3']}" 
allowBody="false">Clay template application - Page 3</span>
- </h3>[[BR]]
- <p>[[BR]]
+ </h3>
+ <p>
-     <span jsfid="outputText" value="#{messages['content.message.page3']}" 
allowBody="false">This is Page 3 content</span>[[BR]]
+     <span jsfid="outputText" value="#{messages['content.message.page3']}" 
allowBody="false">This is Page 3 content</span>
- </p>[[BR]]
- <p>[[BR]]
+ </p>
+ <p>
-     <span jsfid="outputText" value="#{messages['hello']}" 
allowBody="false">Hello</span> <span jsfid="outputText" value="#{person.name}" 
allowBody="false">World</span>[[BR]]
+     <span jsfid="outputText" value="#{messages['hello']}" 
allowBody="false">Hello</span> <span jsfid="outputText" value="#{person.name}" 
allowBody="false">World</span>
- </p>[[BR]]
+ </p>
+ }}}
  
  Here again we refer to the person bean, but this time we are displaying a 
value from it (#{person.name}.  As we mentioned this bean has bean declared 
with session scope, so that the name we entered on page2 is now available on 
page3 for as long as our session exists. We can also refer to any other managed 
bean, and properties in these.
  

Reply via email to