Author: buildbot
Date: Mon Feb 19 00:22:56 2018
New Revision: 1025575

Log:
Production update by buildbot for tapestry

Modified:
    websites/production/tapestry/content/cache/main.pageCache
    websites/production/tapestry/content/default-parameter.html
    websites/production/tapestry/content/error-page-recipe.html
    websites/production/tapestry/content/page-navigation.html
    websites/production/tapestry/content/supporting-informal-parameters.html
    websites/production/tapestry/content/tapestry-for-jsf-users.html

Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.

Modified: websites/production/tapestry/content/default-parameter.html
==============================================================================
--- websites/production/tapestry/content/default-parameter.html (original)
+++ websites/production/tapestry/content/default-parameter.html Mon Feb 19 
00:22:56 2018
@@ -76,7 +76,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>&#160;</p><p>Many of the 
components provided with Tapestry share a common behavior: if the component's 
id matches a property of the container, then some parameter of the component 
(usually value) defaults to that property.</p><div class="aui-label" 
style="float:right" title="Related Articles">
+                <div id="ConfluenceContent"><p>&#160;</p><p>Many of the 
components provided with Tapestry share a common behavior: if the component's 
id matches a property of the container, then some parameter of the component 
(usually value) defaults to that property.</p><div class="aui-label" 
style="float:right; margin: 1em" title="Related Articles">
 
 
 

Modified: websites/production/tapestry/content/error-page-recipe.html
==============================================================================
--- websites/production/tapestry/content/error-page-recipe.html (original)
+++ websites/production/tapestry/content/error-page-recipe.html Mon Feb 19 
00:22:56 2018
@@ -77,7 +77,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><h1 
id="ErrorPageRecipe-ServingTapestryPagesasServletErrorPages">Serving Tapestry 
Pages as Servlet Error Pages</h1><p>Do you want to dress up your site and use a 
snazzy Tapestry page instead of the default 404 error page? Using modern 
servlet containers, this is a snap!</p><div class="aui-label" 
style="float:right" title="Related Articles">
+                <div id="ConfluenceContent"><h1 
id="ErrorPageRecipe-ServingTapestryPagesasServletErrorPages">Serving Tapestry 
Pages as Servlet Error Pages</h1><p>Do you want to dress up your site and use a 
snazzy Tapestry page instead of the default 404 error page? Using modern 
servlet containers, this is a snap!</p><div class="aui-label" 
style="float:right; margin: 1em" title="Related Articles">
 
 
 
@@ -119,7 +119,7 @@
 </div>
 
 
-<p>Simply upgrade your application web.xml to the 2.4 version, and make a 
couple of changes:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>web.xml</b></div><div class="codeContent panelContent pdl">
+<p>Simply upgrade your application web.xml to the 2.4 version (or newer), and 
make a couple of changes:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>web.xml</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
 
 &lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";

Modified: websites/production/tapestry/content/page-navigation.html
==============================================================================
--- websites/production/tapestry/content/page-navigation.html (original)
+++ websites/production/tapestry/content/page-navigation.html Mon Feb 19 
00:22:56 2018
@@ -155,7 +155,18 @@
 </div>
 
 
-<p>In essence, a Tapestry application is a number of related pages, working 
together. To some degree, each page is like an application unto 
itself.</p><p>Any individual request will be targeted at a single page. 
Requests come in two forms:&#160;</p><ul><li><em>component event</em> requests 
target a specific component on a specific page, triggering an event within that 
component</li><li><em>render</em> requests target a specific page, and stream 
the HTML markup for that page back to the client</li></ul><p>This dichotomy 
between component event requests and render requests alleviates a number of 
problems in traditional web applications related to the browser back button, or 
to the user hitting the refresh button in their browser.</p><p><br 
clear="none"><span style="color: rgb(83,145,38);">Logical Page Name 
Shortening</span></p><p>In certain cases, Tapestry will shorten the the logical 
name of a page. For example, the page class 
org.example.pages.address.CreateAddress will be given a l
 ogical name of "address/Create" (the redundant "Address" is removed as a 
suffix). However, this only affects how the page is referenced in URLs; the 
template file will still be CreateAddress.tml, whether on the classpath, or as 
address/CreateAddress.tml (in the web context).</p><p><span>Tapestry actually 
creates multiple names for the name page: "address/Create" and 
"address/CreateAddress" are both synonymous. You can user either in Java code 
that refers to a page by name, or as the page parameter of a 
PageLink.</span></p><h2 
id="PageNavigation-ComponentEventRequests&amp;Responses">Component Event 
Requests &amp; Responses</h2><p>Main Article: <a  
href="page-navigation.html">Page Navigation</a></p><p>Component event requests 
may take the form of hyperlinks (<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/EventLink.html";>EventLink</a>
 or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apa
 che/tapestry5/corelib/components/ActionLink.html">ActionLink</a>) or form 
submissions (<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html";>Form</a>).</p><p>The
 value returned from an <a  href="component-events.html">event handler 
method</a> controls the response sent to the client web browser.</p><p>The URL 
for a component event request identifies the name of the page, the nested id of 
the component, and the name of the event to trigger on the component (specified 
by the "event" parameter of EventLink, or "action" for an ActionLink). Further, 
a component event request may contain additional context information, which 
will be provided to the event handler method.</p><p>These URLs expose a bit of 
the internal structure of the application. Over time, as an application grows 
and is maintained, the ids of components may change. This means that component 
event request URLs should not be bookmarked. Fortunately, user
 s will rarely have the chance to do so (see below).</p><h3 
id="PageNavigation-1.Nullresponse">1. Null response</h3><p>If the event handler 
method returns no value, or returns null, then the current page (the page 
containing the component) will render the response.</p><p>A page render URL for 
the current page is created and sent to the client as a client side redirect. 
The client browser will automatically submit a new request to generate the 
page.</p><p>The user will see the newly generated content in their browser. In 
addition, the URL in the browser's address bar will be a render request URL. 
Render request URLs are shorter and contain less application structure (for 
instance, they don't include component ids or event types). Render requests 
URLs are what your users will bookmark. The component event request URLs are 
transitory, meaningful only while the application is actively engaged, and not 
meant to be used in later sessions.</p><div class="code panel pdl" 
style="border-width:
  1px;"><div class="codeContent panelContent pdl">
+<p>In essence, a Tapestry application is a number of related pages, working 
together. To some degree, each page is like an application unto 
itself.</p><p>Any individual request will be targeted at a single page. 
Requests come in two forms:&#160;</p><ul><li><em>component event</em> requests 
target a specific component on a specific page, triggering an event within that 
component</li><li><em>render</em> requests target a specific page, and stream 
the HTML markup for that page back to the client</li></ul><p>This dichotomy 
between component event requests and render requests alleviates a number of 
problems in traditional web applications related to the browser back button, or 
to the user hitting the refresh button in their browser.</p><h3 
id="PageNavigation-Contents">Contents</h3><h2 
id="PageNavigation-Contents|RelatedArticlesLogicalPageNameShortening"><style 
type="text/css">/*<![CDATA[*/
+div.rbtoc1518999689641 {padding: 0px;}
+div.rbtoc1518999689641 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1518999689641 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></h2><div class="toc-macro rbtoc1518999689641">
+<ul class="toc-indentation"><li><a  
href="#PageNavigation-Contents|RelatedArticlesLogicalPageNameShortening">Logical
 Page Name Shortening</a></li><li><a  
href="#PageNavigation-ComponentEventRequests&amp;Responses">Component Event 
Requests &amp; Responses</a>
+<ul class="toc-indentation"><li><a  href="#PageNavigation-1.Nullresponse">1. 
Null response</a></li><li><a  href="#PageNavigation-2.Stringresponse">2. String 
response</a></li><li><a  href="#PageNavigation-3.Classresponse">3. Class 
response</a></li><li><a  href="#PageNavigation-4.Pageresponse">4. Page 
response</a></li><li><a  href="#PageNavigation-5.HttpError">5. 
HttpError</a></li><li><a  href="#PageNavigation-6.Linkresponse">6. Link 
response</a></li><li><a  href="#PageNavigation-7.Streamresponse">7. Stream 
response</a></li><li><a  href="#PageNavigation-8.URLresponse">8. URL 
response</a></li><li><a  href="#PageNavigation-9.Objectresponse">9. Object 
response</a></li></ul>
+</li><li><a  href="#PageNavigation-PageRenderRequests">Page Render 
Requests</a></li><li><a  href="#PageNavigation-PageActivation">Page 
Activation</a></li><li><a  href="#PageNavigation-PageNavigationPatterns">Page 
Navigation Patterns</a>
+<ul class="toc-indentation"><li><a  
href="#PageNavigation-Pattern1:Componenteventrequests/PersistentData">Pattern 
1: Component event requests / Persistent Data</a></li><li><a  
href="#PageNavigation-Pattern2:ComponentEventRequests/NoPersistentData">Pattern 
2: Component Event Requests / No Persistent Data</a></li><li><a  
href="#PageNavigation-Pattern3:RenderRequestsOnly">Pattern 3: Render Requests 
Only</a></li><li><a  
href="#PageNavigation-Limitations">Limitations</a></li></ul>
+</li></ul>
+</div><br clear="none"><span style="color: rgb(83,145,38);">Logical Page Name 
Shortening</span><p>In certain cases, Tapestry will shorten the the logical 
name of a page. For example, the page class 
org.example.pages.address.CreateAddress will be given a logical name of 
"address/Create" (the redundant "Address" is removed as a suffix). However, 
this only affects how the page is referenced in URLs; the template file will 
still be CreateAddress.tml, whether on the classpath, or as 
address/CreateAddress.tml (in the web context).</p><p><span>Tapestry actually 
creates multiple names for the name page: "address/Create" and 
"address/CreateAddress" are both synonymous. You can user either in Java code 
that refers to a page by name, or as the page parameter of a 
PageLink.</span></p><h2 
id="PageNavigation-ComponentEventRequests&amp;Responses">Component Event 
Requests &amp; Responses</h2><p>Main Article:&#160; <a  
href="component-events.html">Component Events</a></p><p>Component event 
requests 
 may take the form of hyperlinks (<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/EventLink.html";>EventLink</a>
 or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html";>ActionLink</a>)
 or form submissions (<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html";>Form</a>).</p><p>The
 value returned from an <a  href="component-events.html">event handler 
method</a> controls the response sent to the client web browser.</p><p>The URL 
for a component event request identifies the name of the page, the nested id of 
the component, and the name of the event to trigger on the component (specified 
by the "event" parameter of EventLink, or "action" for an ActionLink). Further, 
a component event request may contain additional context information, which 
will be provided to the event handl
 er method.</p><p>These URLs expose a bit of the internal structure of the 
application. Over time, as an application grows and is maintained, the ids of 
components may change. This means that component event request URLs should not 
be bookmarked. Fortunately, users will rarely have the chance to do so (see 
below).</p><h3 id="PageNavigation-1.Nullresponse">1. Null response</h3><p>If 
the event handler method returns no value, or returns null, then the current 
page (the page containing the component) will render the response.</p><p>A page 
render URL for the current page is created and sent to the client as a client 
side redirect. The client browser will automatically submit a new request to 
generate the page.</p><p>The user will see the newly generated content in their 
browser. In addition, the URL in the browser's address bar will be a render 
request URL. Render request URLs are shorter and contain less application 
structure (for instance, they don't include component ids or event type
 s). Render requests URLs are what your users will bookmark. The component 
event request URLs are transitory, meaningful only while the application is 
actively engaged, and not meant to be used in later sessions.</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public Object onAction(){
   return null;
 }</pre>
@@ -203,7 +214,7 @@ public Object onAction(){
   long onPassivate() { return product.getId(); }
 }
 </pre>
-</div></div><p>The activation context may consist of a series of values, in 
which case the return value of the method should be an array or a List.</p><div 
class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Note: If you are using the <a  
href="hibernate-user-guide.html">tapestry-hibernate</a> integration library and 
your passivate context is a Hibernate entity, then you can just use the entity 
itself, not its id. Tapestry will automatically extract the entity's id into 
the URL, and convert it back for the "activate" event handler 
method.</p></div></div><h2 id="PageNavigation-Pageactivation">Page 
activation</h2><p>When a page render request arrives, the page is 
<em>activated</em> before it is rendered.</p><div class="navmenu" 
style="float:right; background:#eee; margin:3px; padding:0 1em">
+</div></div><p>The activation context may consist of a series of values, in 
which case the return value of the method should be an array or a List.</p><div 
class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Note: If you are using the <a  
href="hibernate-user-guide.html">tapestry-hibernate</a> integration library and 
your passivate context is a Hibernate entity, then you can just use the entity 
itself, not its id. Tapestry will automatically extract the entity's id into 
the URL, and convert it back for the "activate" event handler 
method.</p></div></div><h2 id="PageNavigation-PageActivation">Page 
Activation</h2><p>When a page render request arrives, the page is 
<em>activated</em> before it is rendered.</p><div class="navmenu" 
style="float:right; background:#eee; margin:3px; padding:0 1em">
 <p>    <strong>JumpStart Demos:</strong><br clear="none">
     <a  class="external-link" 
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/navigation/onactivateandonpassivate/3";
 rel="nofollow">onActivate and onPassivate</a><br clear="none">
     <a  class="external-link" 
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/handlingabadcontext/1";
 rel="nofollow">Handling A Bad Context</a></p></div>Activation serves two 
purposes:<ul><li>It allows the page to restore its internal state from data 
encoded into the URL (the activation context discussed above).</li><li>It 
provides coarse approach to validating access to the page.</li></ul><p>The 
later case &#8211; validation&#160;&#8211; is generally concerned with user 
identity and access; if you have pages that may only be accessed by certain 
users, you may use the page's activate event handler for verifying that 
access.</p><p>Page activation uses Tapestry's <em>Component Event</em> 
mechanism. See&#160;<a  href="component-events.html">Component Events</a> for 
details.</p><p>A page's activate event handler mirrors its passivate 
handler:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">

Modified: 
websites/production/tapestry/content/supporting-informal-parameters.html
==============================================================================
--- websites/production/tapestry/content/supporting-informal-parameters.html 
(original)
+++ websites/production/tapestry/content/supporting-informal-parameters.html 
Mon Feb 19 00:22:56 2018
@@ -75,7 +75,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>&#160;<strong>Informal 
parameters</strong> are any additional parameters (aka HTML attributes) beyond 
the those explicitly defined for a component using the <a  
class="external-link" 
href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/annotations/Parameter.html";>Parameter</a>
 annotation.</p><div class="aui-label" style="float:right" title="Related 
Articles">
+                <div id="ConfluenceContent"><p>&#160;<strong>Informal 
parameters</strong> are any additional parameters (aka HTML attributes) beyond 
the those explicitly defined for a component using the @<a  
class="external-link" 
href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/annotations/Parameter.html";>Parameter</a>
 annotation.</p><div class="aui-label" style="float:right; margin: 1em" 
title="Related Articles">
 
 
 
@@ -126,7 +126,7 @@
 </div>
 
 
-<p>Any component that closely emulates a particular HTML element 
<strong><em>should</em></strong> support informal parameters, because it gives 
users of your component the ability to easily add HTML attributes to the HTML 
that your component emits. You'll find that most of the built-in Tapestry 
components, such as Form, Label and TextField, do exactly that.</p><p>To 
support informal parameters, a component class should use either the @<a  
class="external-link" 
href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/annotations/SupportsInformalParameters.html";>SupportsInformalParameters</a>
 annotation or the RenderInformals mixin. Otherwise, providing informal 
parameters to a component will do nothing: any additional parameters will be 
ignored.</p><h3 
id="SupportingInformalParameters-Approach1:@SupportsInformalParameters">Approach
 1: @SupportsInformalParameters</h3><p>In the example below we create an Img 
component, a custom replacement for the &lt;img&gt; tag. Its sr
 c parameter will be an asset. We'll use the @SupportsInformalParameters 
annotation to tell Tapestry that the component should support informal 
parameters.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<p>Any component that closely emulates a particular HTML element 
<strong><em>should</em></strong> support informal parameters, because it gives 
users of your component the ability to easily add HTML attributes to the HTML 
that your component emits. You'll find that most of the built-in Tapestry 
components, such as Form, Label and TextField, do exactly that.</p><p>To 
support informal parameters, a component class should use either the @<a  
class="external-link" 
href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/annotations/SupportsInformalParameters.html";>SupportsInformalParameters</a>
 annotation or the RenderInformals mixin. Otherwise, providing informal 
parameters to a component will do nothing: any additional parameters will be 
ignored.</p><h3 
id="SupportingInformalParameters-Approach1:@SupportsInformalParameters">Approach
 1: @SupportsInformalParameters</h3><p>In the example below we create an Img 
component, a custom replacement for the &lt;img&gt; tag. Its sr
 c parameter will be an asset. We'll use the @SupportsInformalParameters 
annotation to tell Tapestry that the component should support informal 
parameters.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Img.java</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@SupportsInformalParameters
 public class Img
 {
@@ -145,7 +145,7 @@ public class Img
     }
 }
 </pre>
-</div></div><p>The call to renderInformalParameters() is what converts and 
outputs the informal parameters. It should occur <em>after</em> your code has 
rendered attributes into the element (earlier written attributes will 
<em>not</em> be overwritten by later written attributes).</p><p>Returning false 
from beginRender() ensures that the body of the component is not rendered, 
which makes sense for an &lt;img&gt; tag, which has no body.</p><h3 
id="SupportingInformalParameters-Approach2:RenderInformals">Approach 2: 
RenderInformals</h3><p>Another, equivalent, approach is to use the <a  
class="external-link" 
href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/corelib/mixins/RenderInformals.html";>RenderInformals</a>
 mixin:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+</div></div><p>The call to renderInformalParameters() is what converts and 
outputs the informal parameters. It should occur <em>after</em> your code has 
rendered attributes into the element (earlier written attributes will 
<em>not</em> be overwritten by later written attributes).</p><p>Returning false 
from beginRender() ensures that the body of the component is not rendered, 
which makes sense for an &lt;img&gt; tag, which has no body.</p><h3 
id="SupportingInformalParameters-Approach2:RenderInformals">Approach 2: 
RenderInformals</h3><p>Another, equivalent, approach is to use the <a  
class="external-link" 
href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/corelib/mixins/RenderInformals.html";>RenderInformals</a>
 mixin (:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Img.java</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class Img
 {
     @Parameter(required=true, allowNull=false, 
defaultPrefix=BindingConstants.ASSET)
@@ -166,7 +166,9 @@ public class Img
     }
 }
 </pre>
-</div></div><p>This variation splits the rendering of the tag in two pieces, 
so that the RenderInformals mixin can operate (after beginRender() and before 
beforeRenderBody()).</p></div>
+</div></div><p>This variation splits the rendering of the tag in two pieces, 
so that the RenderInformals mixin can operate (after beginRender() and before 
beforeRenderBody()).</p><h3 
id="SupportingInformalParameters-Approach3:Extendthe&quot;Any&quot;component">Approach
 3: Extend the "Any" component</h3><p>Another approach is to have your 
component class <em>extend</em> Tapestry's Any component, which already 
supports informal parameters:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Img.java</b></div><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class Img extends Any { ... }</pre>
+</div></div><p>&#160;</p><p>&#160;</p><p>&#160;</p><p>&#160;</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/tapestry-for-jsf-users.html
==============================================================================
--- websites/production/tapestry/content/tapestry-for-jsf-users.html (original)
+++ websites/production/tapestry/content/tapestry-for-jsf-users.html Mon Feb 19 
00:22:56 2018
@@ -136,7 +136,7 @@
 </div>
 
 
-<p>Since almost all modern JSF applications use Facelets as their view 
technology, we assume the use of Facelets here when discussing JSF 
features.</p><p>JSF is a rich, mature web framework specification, and there 
are lots of smart people who use it productively. This guide isn't intended as 
a pro-versus-con comparison or as advocacy of any kind. Instead, it just 
attempts to make transitions between the two frameworks easier, regardless of 
the reason for doing so.</p><h2 
id="TapestryforJSFUsers-Side-by-sideComparison">Side-by-side 
Comparison</h2><p>JSF and Tapestry have a lot of superficial similarities, so 
the first steps in that transition are all about relating similar concepts, 
terms and components in your mind:</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Concepts &amp; Terminology</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><
 p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Java class associated with a page or 
component</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>"Backing 
Bean"</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>"<a  
href="tapestry-for-jsf-users.html">Component Class</a>"</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Component 
attributes/parameters</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"attributes"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"<a  
href="tapestry-for-jsf-users.html">parameters</a>"</p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Common 
Attributes/Parameters</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>HTML Attribute used for invisible 
instrumentation</p></td><td colspan="1" rowspan="1
 " class="confluenceTd"><p>jsfc="someComponentType"</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  
href="tapestry-for-jsf-users.html">t:type="someComponentType"</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>CSS "class" attribute 
name</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>styleClass</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>class</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Alternating "zebra" striped rows</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>rowclasses="class1,class2"</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>class="${cycle:class1,class2}" using <a  
class="external-link" 
href="https://wiki.apache.org/tapestry/Tapestry5HowToAddBindingPrefixCycle";>cycle
 binding prefix</a>, or with CSS: .rowClass:nth-child(even) {background-color: 
#e8e8e8;}</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Output and Messages</p></th><th 
 colspan="1" rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Escaped HTML from property</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:outputText 
value="myBean.myValue"/&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${myValue}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Raw HTML from property</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>#{myBean.myValue}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/OutputRaw.html";>&lt;t:outputRaw
 value="myValue"/&gt;</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Error messages</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:message&gt; and &lt;h:messages&gt;</p></td><td 
colsp
 an="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Error.html";>&lt;t:error&gt;</a>
 and <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Errors.html";>&lt;t:errors&gt;</a>
 (for forms) or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Alerts.html";>&lt;t:alerts&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Image display</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:graphicImage&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>use standard &lt;img&gt; 
tag</em></p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Conditionals and Looping</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry
 </p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Render-time loop</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;ui:repeat&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Loop.html";>&lt;t:loop&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Compile-time loop</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;c:forEach&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Loop.html";>&lt;t:loop&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Conditional</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;c:if 
test="#{myBean.myValue}"&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="externa
 l-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/If.html";>&lt;t:if
 test="myValue"&gt;</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Conditional</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;ui:fragment 
rendered="#{myBean.someCondition}"/&gt;...&lt;/ui:fragment&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/If.html";>&lt;t:if
 test="someCondition"&gt;...&lt;/t:if&gt;</a></p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Switch</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;c:choose&gt;&lt;c:when ... 
&gt;&lt;/c:choose&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>See <a  href="tapestry-for-jsf-users.html">Tapestry for 
JSF Users</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Server-side c
 omment</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;ui:remove&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  
href="tapestry-for-jsf-users.html">&lt;t:remove&gt;</a></p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Links and Buttons</p></th><th 
colspan="1" rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Navigational link</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>&lt;h:link 
outcome="nextpage.xhtml"/&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/PageLink.html";>&lt;t:pagelink
 page="nextpage"/&gt;</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Event-triggering link, without form 
submission</p></td><td colspan="1" rowspan="1" cl
 ass="confluenceTd"><p><em>not available</em></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html";>&lt;t:actionLink&gt;</a>
 or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/EventLink.html";>&lt;t:eventLink&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Form submission 
link</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:commandLink&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/LinkSubmit.html";>&lt;t:linkSubmit&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Form submission 
button</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:commandButton&gt;</p></td><td 
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Submit.html";>&lt;t:submit&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Link to Javascript 
file</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:outputScript&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>&lt;script&gt; or use @Import in 
component class</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Link to CSS file</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:outputStylesheet&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>&lt;style&gt; or use @Import in 
component class</em></p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Grids, Tables and Trees</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p
 >Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
 >class="confluenceTd"><p>Tabular data in &lt;table&gt;</p></td><td colspan="1" 
 >rowspan="1" class="confluenceTd"><p>&lt;h:datatable&gt;</p></td><td 
 >colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
 >href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Grid.html";>&lt;t:grid&gt;</a></p></td></tr><tr><td
 > colspan="1" rowspan="1" class="confluenceTd"><p>Table used for 
 >layout</p></td><td colspan="1" rowspan="1" 
 >class="confluenceTd"><p>&lt;h:panelGrid&gt; with 
 >&lt;h:panelGroup&gt;</p></td><td colspan="1" rowspan="1" 
 >class="confluenceTd"><p><em>use standard &lt;table&gt; 
 >tag</em></p></td></tr><tr><td colspan="1" rowspan="1" 
 >class="confluenceTd"><p>Hierarchical tree</p></td><td colspan="1" rowspan="1" 
 >class="confluenceTd"><p><em>depends on component library</em></p></td><td 
 >colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
 >href="http://tapestry.apache.org/cu
 
rrent/apidocs/org/apache/tapestry5/corelib/components/Tree.html">&lt;t:tree&gt;</a></p></td></tr><tr><th
 colspan="1" rowspan="1" class="confluenceTh"><p>Form 
Tags/Components</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Form</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:form&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html";>&lt;t:form&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Single-line text input 
field</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputText&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/co
 relib/components/TextField.html">&lt;t:textField&gt;</a></p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Password field</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputSecret&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/PasswordField.html";>&lt;t:passwordfield&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Select menu</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectOneMenu&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Select.html";>&lt;t:select&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Checkbox</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectBooleanCheckbox&gt;</p></td
 ><td colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
 >href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Checkbox.html";>&lt;t:checkbox&gt;</a></p></td></tr><tr><td
 > colspan="1" rowspan="1" class="confluenceTd"><p>Checkbox list</p></td><td 
 >colspan="1" rowspan="1" 
 >class="confluenceTd"><p>&lt;h:selectManyCheckbox&gt;</p></td><td colspan="1" 
 >rowspan="1" class="confluenceTd"><p><a  class="external-link" 
 >href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Checklist.html";>&lt;t:checklist&gt;</a></p></td></tr><tr><td
 > colspan="1" rowspan="1" class="confluenceTd"><p>Radio button 
 >list</p></td><td colspan="1" rowspan="1" 
 >class="confluenceTd"><p>&lt;h:selectOneRadio&gt;</p></td><td colspan="1" 
 >rowspan="1" class="confluenceTd"><p><a  class="external-link" 
 >href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/RadioGroup.html";>&lt;t:radioGroup&gt;</a>
 > with <a  class=
 "external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Radio.html";>&lt;t:radio&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Multiple select 
menu</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectManyListbox&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>not available</em> (but see Palette and 
Checklist)</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Hidden field</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputHidden&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Hidden.html";>&lt;t:hidden&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>textarea tag</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputTextarea&gt;</p></td><td colspan="1" rows
 pan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/TextArea.html";>&lt;t:textArea&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Label tag</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:outputLabel 
for="..."&gt;</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Label.html";>&lt;t:label
 for="..."&gt;</a></p></td></tr></tbody></table></div><p>Some important 
notes:</p><ul><li>With Tapestry, you don't use the ${...} syntax with 
parameters of components. Just use a bare expression within the quotes. For 
example: &lt;t:textfield value="myProperty"&gt; instead of &lt;t:textfield 
value="${myProperty}"&gt;, because in the latter case the expression is 
converted to a read-only string before the textfield component gets it.</li></
 ul><h2 id="TapestryforJSFUsers-HelloWorldComparison">Hello World 
Comparison</h2><p>Faces templates and Tapestry templates are superficially 
quite similar.</p><div class="sectionColumnWrapper"><div 
class="sectionMacro"><div class="sectionMacroRow"><div class="columnMacro"><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>JSF template 
(helloworld.xhtml)</b></div><div class="codeContent panelContent pdl">
+<p>Since almost all modern JSF applications use Facelets as their view 
technology, we assume the use of Facelets here when discussing JSF 
features.</p><p>JSF is a rich, mature web framework specification, and there 
are lots of smart people who use it productively. This guide isn't intended as 
a pro-versus-con comparison or as advocacy of any kind. Instead, it just 
attempts to make transitions between the two frameworks easier, regardless of 
the reason for doing so.</p><h2 
id="TapestryforJSFUsers-Side-by-sideComparison">Side-by-side 
Comparison</h2><p>JSF and Tapestry have a lot of superficial similarities, so 
the first steps in that transition are all about relating similar concepts, 
terms and components in your mind:</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Concepts &amp; Terminology</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><
 p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Java class associated with a page or 
component</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>"Backing 
Bean"</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>"<a  
href="component-classes.html">Component Class</a>"</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Component 
attributes/parameters</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"attributes"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"<a  
href="component-parameters.html">parameters</a>"</p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Common 
Attributes/Parameters</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>HTML Attribute used for invisible 
instrumentation</p></td><td colspan="1" rowspan="1" class
 ="confluenceTd"><p>jsfc="someComponentType"</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  
href="component-templates.html">t:type="someComponentType"</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>CSS "class" attribute 
name</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>styleClass</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>class</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Alternating "zebra" striped rows</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>rowclasses="class1,class2"</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>class="${cycle:class1,class2}" using <a  
class="external-link" 
href="https://wiki.apache.org/tapestry/Tapestry5HowToAddBindingPrefixCycle";>cycle
 binding prefix</a>, or with CSS: .rowClass:nth-child(even) {background-color: 
#e8e8e8;}</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Output and Messages</p></th><th colspan="1
 " rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Escaped HTML from property</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>&lt;h:outputText 
value="myBean.myValue"/&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${myValue}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Raw HTML from property</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>#{myBean.myValue}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/OutputRaw.html";>&lt;t:outputRaw
 value="myValue"/&gt;</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Error messages</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:message&gt; and &lt;h:messages&gt;</p></td><td 
colspan="1" row
 span="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Error.html";>&lt;t:error&gt;</a>
 and <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Errors.html";>&lt;t:errors&gt;</a>
 (for forms) or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Alerts.html";>&lt;t:alerts&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Image display</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:graphicImage&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>use standard &lt;img&gt; tag, but see 
<a  href="assets.html">Assets</a><br clear="none"></em></p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Conditionals and 
Looping</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF</p></th><th colspa
 n="1" rowspan="1" class="confluenceTh"><p>Tapestry</p></th></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Render-time loop</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;ui:repeat&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Loop.html";>&lt;t:loop&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Compile-time loop</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;c:forEach&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Loop.html";>&lt;t:loop&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Conditional</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;c:if 
test="#{myBean.myValue}"&gt;</p></td><td colspan="1" rows
 pan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/If.html";>&lt;t:if
 test="myValue"&gt;</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Conditional</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;ui:fragment 
rendered="#{myBean.someCondition}"/&gt;...&lt;/ui:fragment&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/If.html";>&lt;t:if
 test="someCondition"&gt;...&lt;/t:if&gt;</a></p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Switch</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;c:choose&gt;&lt;c:when ... 
&gt;&lt;/c:choose&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>See <a  href="switching-cases.html">Switching 
Cases</a></p></td></tr><tr><td colspan="1" rowspan="1" c
 lass="confluenceTd"><p>Server-side comment</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;ui:remove&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  
href="component-templates.html">&lt;t:remove&gt;</a></p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Links and Buttons</p></th><th 
colspan="1" rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Navigational link</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>&lt;h:link 
outcome="nextpage.xhtml"/&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/PageLink.html";>&lt;t:pagelink
 page="nextpage"/&gt;</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Event-triggering link, without form submission</p></
 td><td colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html";>&lt;t:actionLink&gt;</a>
 or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/EventLink.html";>&lt;t:eventLink&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Form submission 
link</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:commandLink&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/LinkSubmit.html";>&lt;t:linkSubmit&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Form submission 
button</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>&lt
 ;h:commandButton&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Submit.html";>&lt;t:submit&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Link to Javascript 
file</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:outputScript&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>&lt;script&gt; or use @Import in 
component class</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Link to CSS file</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:outputStylesheet&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>&lt;style&gt; or use @Import in 
component class</em></p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Grids, Tables and Trees</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" ro
 wspan="1" class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Tabular data in &lt;table&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:datatable&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Grid.html";>&lt;t:grid&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Table used for 
layout</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:panelGrid&gt; with 
&lt;h:panelGroup&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>use standard &lt;table&gt; 
tag</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Hierarchical tree</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>depends on component library</em></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" hr
 
ef="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Tree.html";>&lt;t:tree&gt;</a></p></td></tr><tr><th
 colspan="1" rowspan="1" class="confluenceTh"><p>Form 
Tags/Components</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Form</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:form&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html";>&lt;t:form&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Single-line text input 
field</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputText&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/curren
 
t/apidocs/org/apache/tapestry5/corelib/components/TextField.html">&lt;t:textField&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Password field</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputSecret&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/PasswordField.html";>&lt;t:passwordfield&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Select menu</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectOneMenu&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Select.html";>&lt;t:select&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Checkbox</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:
 selectBooleanCheckbox&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Checkbox.html";>&lt;t:checkbox&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Checkbox list</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectManyCheckbox&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Checklist.html";>&lt;t:checklist&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Radio button list</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectOneRadio&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/RadioGroup.html";>&lt;t:r
 adioGroup&gt;</a> with <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Radio.html";>&lt;t:radio&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Multiple select 
menu</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectManyListbox&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>not available</em> (but see Palette and 
Checklist)</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Hidden field</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputHidden&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Hidden.html";>&lt;t:hidden&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>textarea tag</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:inputTextarea
 &gt;</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/TextArea.html";>&lt;t:textArea&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Label tag</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:outputLabel 
for="..."&gt;</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Label.html";>&lt;t:label
 for="..."&gt;</a></p></td></tr></tbody></table></div><p>Some important 
notes:</p><ul><li>With Tapestry, you don't use the ${...} syntax with 
parameters of components. Just use a bare expression within the quotes. For 
example: &lt;t:textfield value="myProperty"&gt; instead of &lt;t:textfield 
value="${myProperty}"&gt;, because in the latter case the expression is 
converted to a read-only string before the te
 xtfield component gets it.</li></ul><h2 
id="TapestryforJSFUsers-HelloWorldComparison">Hello World 
Comparison</h2><p>Faces templates and Tapestry templates are superficially 
quite similar.</p><div class="sectionColumnWrapper"><div 
class="sectionMacro"><div class="sectionMacroRow"><div class="columnMacro"><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>JSF template 
(helloworld.xhtml)</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;html xmlns="http://www.w3.org/1999/xhtml";
         xmlns:h="http://java.sun.com/jsf/html"&gt;
   &lt;h:body&gt;
@@ -167,13 +167,13 @@ public class HelloWorldBean {
     }
 }
 </pre>
-</div></div></div></div></div></div><h2 
id="TapestryforJSFUsers-Expressionsintemplates">Expressions in 
templates</h2><p>JSF uses the Unified Expression Language with the #{...} or 
${...} syntax for accessing Backing Bean properties. For its part, Tapestry 
uses the ${...} syntax with a similar but intentially limited expression 
language called <a  href="tapestry-for-jsf-users.html">Tapestry for JSF 
Users</a>. Both allow easy access to properties via the usual JavaBean 
conventions, but with Tapestry you don't have to specify which class the 
expression starts at (because it always starts at the component class 
corresponding to the template). Some comparisons:</p><div 
class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>&#160;</p></td><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF Syntax</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry Syntax</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confl
 uenceTd"><p>Property (calls getEmployeeName() or 
setEmployeeName())</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{employeeBean.employeeName}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${employeeName}</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Boolean property (calls 
isHourly() or setHourly())</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{employeeBean.hourly}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${hourly}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Property chain</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>#{employeeBean.address.street}</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>${address.street}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Null-safe property chain</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>#{employeeBean.address.street}</p></td><td colspan="1" 
rowspan="1" class="confluence
 Td"><p>${address?.street}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>5th element in a List</p></td><td colspan="1" 
rowspan="1" 
class="confluenceTd"><p>#{employeeBean.employees[5].name}</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>${employees.get(5).name}</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Negation</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>#{! 
employeeBean.hourly}</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${! hourly}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Arithmetic &amp; relational 
operators</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>+-*/% div 
mod</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Relational operators</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>== != ne &lt; lt &gt; gt &lt;= le &gt;= 
ge</p></td><
 td colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Ternary operator</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{myBean.foo &lt; 0 ? 'bar' : 'baz'}</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Method calling</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{myBean.employees.size()}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${employees.size()}</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Iterated Range</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
avaialble</em></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${1..10}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Iterated Range (calculated)</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>not avaia
 lble</em></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${1..groupList.size()}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>List</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>not available</em></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${ [ <a  class="external-link" 
href="http://user.name"; rel="nofollow">user.name</a>, user.email, user.phone ] 
}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Map</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>not available</em></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${ { 'id':'4039','type':'hourly' } 
}</p></td></tr></tbody></table></div><p>Features shown as <em>not 
available</em> above are absent by design, because (in both Tapestry and JSF) 
it is considered best to keep complex logic in the component class rather than 
in the template.</p><h2 
id="TapestryforJSFUsers-EventHandling&amp;PageNavigation">Event Handling &amp
 ; Page Navigation</h2><h3 id="TapestryforJSFUsers-Eventhandling">Event 
handling</h3><p>In JSF, you specify the event via the <code>action</code> 
parameter (for example, &lt;h:commandButton value="Submit" 
action="employeeBean.saveChanges"&gt;). For Tapestry, event handler methods are 
found by method naming conventions (onSomeEvent() or by method annotations 
(@Event), based on a combination of the "t:id" attribute and event name, and 
the action name used depends on the component. For example, the 
"&lt;t:actionlink&gt;" component in Tapestry emits an "action" event when 
clicked, and you handle that event in your "onAction()" method.</p><h2 
id="TapestryforJSFUsers-Validation">Validation</h2><p>Tapestry applications can 
use JSR 303 Bean Validation annotations that JSF users should be familiar 
with:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+</div></div></div></div></div></div><h2 
id="TapestryforJSFUsers-Expressionsintemplates">Expressions in 
templates</h2><p>JSF uses the Unified Expression Language with the #{...} or 
${...} syntax for accessing Backing Bean properties. For its part, Tapestry 
uses the ${...} syntax with a similar but intentionally limited expression 
language called <a  href="property-expressions.html">Property Expressions</a>. 
Both allow easy access to properties via the usual JavaBean conventions, but 
with Tapestry you don't have to specify which class the expression starts at 
(because it always starts at the component class corresponding to the 
template). Some comparisons:</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&#160;</p></td><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF Syntax</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry Syntax</p></th></tr><tr><td colspan="1" 
rowspan="1" class="conflue
 nceTd"><p>Property (calls getEmployeeName() or setEmployeeName())</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>#{employeeBean.employeeName}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${employeeName}</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Boolean property (calls 
isHourly() or setHourly())</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{employeeBean.hourly}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${hourly}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Property chain</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>#{employeeBean.address.street}</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>${address.street}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Null-safe property chain</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>#{employeeBean.address.street}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd
 "><p>${address?.street}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>5th element in a List</p></td><td colspan="1" 
rowspan="1" 
class="confluenceTd"><p>#{employeeBean.employees[5].name}</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>${employees.get(5).name}</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Negation</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>#{! 
employeeBean.hourly}</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${! hourly}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Arithmetic &amp; relational 
operators</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>+-*/% div 
mod</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Relational operators</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>== != ne &lt; lt &gt; gt &lt;= le &gt;= 
ge</p></td><td
  colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Ternary operator</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{myBean.foo &lt; 0 ? 'bar' : 'baz'}</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Method calling</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{myBean.employees.size()}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${employees.size()}</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Iterated Range</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
avaialble</em></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${1..10}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Iterated Range (calculated)</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>not avaialb
 le</em></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${1..groupList.size()}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>List</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>not available</em></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${ [ <a  class="external-link" 
href="http://user.name"; rel="nofollow">user.name</a>, user.email, user.phone ] 
}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Map</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>not available</em></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${ { 'id':'4039','type':'hourly' } 
}</p></td></tr></tbody></table></div><p>Features shown as <em>not 
available</em> above are absent by design, because (in both Tapestry and JSF) 
it is considered best to keep complex logic in the component class rather than 
in the template.</p><h2 
id="TapestryforJSFUsers-EventHandling&amp;PageNavigation">Event Handling &amp; 
 Page Navigation</h2><h3 id="TapestryforJSFUsers-Eventhandling">Event 
handling</h3><p>In JSF, you specify the event via the <code>action</code> 
parameter (for example, &lt;h:commandButton value="Submit" 
action="employeeBean.saveChanges"&gt;). For Tapestry, event handler methods are 
found by method naming conventions (onSomeEvent() or by method annotations 
(@Event), based on a combination of the "t:id" attribute and event name, and 
the action name used depends on the component. For example, the 
"&lt;t:actionlink&gt;" component in Tapestry emits an "action" event when 
clicked, and you handle that event in your "onAction()" method.</p><h2 
id="TapestryforJSFUsers-Validation">Validation</h2><p>Tapestry applications can 
use JSR 303 Bean Validation annotations that JSF users should be familiar 
with:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class Employee {
     @Validate("required,minlength=2,maxlength=100")
     private String lastName;
     @NotNull @Email private String email;
 </pre>
-</div></div><h3 
id="TapestryforJSFUsers-Post-Redirect-GetNavigation">Post-Redirect-Get 
Navigation</h3><p>By default, most JSF URLs are "one page behind". That is, 
when you click on an &lt;h:commandLink&gt; link or submit a form, the request 
goes back to the originating page, and the server returns the contents of the 
<strong>next</strong> page &#8211; but the URL in the browser shows the 
previous page's URL. To fix this in JSF you add the "?faces-redirect=true" to 
the URL you return from event handlers, which causes JSF to send a redirect to 
the browser to navigate to the next page.</p><p>By contrast, Tapestry 
implements this Post-Redirect-Get pattern by default. The URL will always 
reflect the page you're seeing, not the page you just came from.</p><p>Note 
that by default Tapestry does not save property values across the 
Post-Redirect-Get cycle. This means that you have to consider how (and whether) 
to persist property values from one page to the next. The usual solution is to 
eith
 er make the values part of the page's <a  
href="tapestry-for-jsf-users.html">Activation Context</a> (which means the 
values will be appended to the URL) or <a  
href="tapestry-for-jsf-users.html">@Persist the properties</a> the values in 
the session.</p><h2 
id="TapestryforJSFUsers-CustomandCompositeComponents">Custom and Composite 
Components</h2><p>With JSF, creating custom components is an <a  
class="external-link" 
href="http://jsfcorner.blogspot.com/2011/01/custom-components.html"; 
rel="nofollow">advanced topic</a>. In fact, many JSF developers have 
<em>never</em> created a custom component. In JSF 1.x, creating each custom 
component requires a lot of work: creating 3 Java classes (component, component 
renderer and component tag), registering the component in an XML file, and 
registering the tag in the .tld file. In JSF 2.x <em>composite components</em> 
can be created without too much work (if your needs can be met by combining 
existing components <em>and</em> you don't need any cus
 tom Java), but you still have to use cumbersome &lt;composite:interface&gt; 
and &lt;composite:implementation&gt; tags in your component templates, and you 
have to list the composite components in the xml namespace declaration at the 
top of the pages where you are using them.</p><p>Creating true custom 
components in JSF 2.0 still requires several steps: create a component class 
(generally having the @FacesComponent annotation and extending 
UIComponentBase), create a renderer class (generally extending Renderer), add a 
&lt;renderer&gt; section to the facesconfig file, and create a *-taglib.xml 
file in the WEB_INF folder that defines the namespace, tag and component type 
of the custom component.</p><p>In contrast, with Tapestry, <a  
href="tapestry-for-jsf-users.html">creating custom components</a> is a 
<em>beginner</em> topic: it is expected to be a daily activity for developers, 
because it is so easy. In fact, the steps are the same as creating a page. All 
you have to do is create a (
 potentially empty) Java class in a "components" sub-package, and create a 
template file containing (X)HTML markup in the corresponding "components" 
sub-folder within your package hierarchy under /src/main/resources. You 
<em>use</em> a custom component just like you use any built-in Tapestry 
component: <code>&lt;t:mycomponent&gt;</code>.</p><p>Because they're so easy to 
create, Tapestry applications tend to have a lot of custom components and much 
less repetition of HTML than most JSF applications.</p><h2 
id="TapestryforJSFUsers-OtherReferences">Other References</h2><ul><li><a  
class="external-link" 
href="http://blog.tapestry5.de/wp-content/uploads/2010/06/JSF-2.0-vs-Tapestry-5.pdf";
 rel="nofollow">JavaServer Faces 2.0 vs. Tapestry 5: A Head-to-Head 
Comparison</a> slides by Igor Drobiazko, June 2010.</li><li><a  
class="external-link" 
href="http://docs.oracle.com/javaee/6/tutorial/doc/gkhxa.html"; 
rel="nofollow">Composite Components: Advanced Topics and Example</a> part of 
<em>The Java 
 EE 6 Tutorial</em> from Oracle</li></ul><p>&#160;</p><p></p></div>
+</div></div><h3 
id="TapestryforJSFUsers-Post-Redirect-GetNavigation">Post-Redirect-Get 
Navigation</h3><p>By default, most JSF URLs are "one page behind". That is, 
when you click on an &lt;h:commandLink&gt; link or submit a form, the request 
goes back to the originating page, and the server returns the contents of the 
<strong>next</strong> page &#8211; but the URL in the browser shows the 
previous page's URL. To fix this in JSF you add the "?faces-redirect=true" to 
the URL you return from event handlers, which causes JSF to send a redirect to 
the browser to navigate to the next page.</p><p>By contrast, Tapestry 
implements this Post-Redirect-Get pattern by default. The URL will always 
reflect the page you're seeing, not the page you just came from.</p><p>Note 
that by default Tapestry does not save property values across the 
Post-Redirect-Get cycle. This means that you have to consider how (and whether) 
to persist property values from one page to the next. The usual solution is to 
eith
 er make the values part of the page's <a  
href="page-navigation.html">Activation Context</a> (which means the values will 
be appended to the URL) or <a  href="persistent-page-data.html">@Persist the 
properties</a> the values in the session.</p><h2 
id="TapestryforJSFUsers-CustomandCompositeComponents">Custom and Composite 
Components</h2><p>With JSF, creating custom components is an <a  
class="external-link" 
href="http://jsfcorner.blogspot.com/2011/01/custom-components.html"; 
rel="nofollow">advanced topic</a>. In fact, many JSF developers have 
<em>never</em> created a custom component. In JSF 1.x, creating each custom 
component requires a lot of work: creating 3 Java classes (component, component 
renderer and component tag), registering the component in an XML file, and 
registering the tag in the .tld file. In JSF 2.x <em>composite components</em> 
can be created without too much work (if your needs can be met by combining 
existing components <em>and</em> you don't need any custom Java)
 , but you still have to use cumbersome &lt;composite:interface&gt; and 
&lt;composite:implementation&gt; tags in your component templates, and you have 
to list the composite components in the xml namespace declaration at the top of 
the pages where you are using them.</p><p>Creating true custom components in 
JSF 2.0 still requires several steps: create a component class (generally 
having the @FacesComponent annotation and extending UIComponentBase), create a 
renderer class (generally extending Renderer), add a &lt;renderer&gt; section 
to the facesconfig file, and create a *-taglib.xml file in the WEB_INF folder 
that defines the namespace, tag and component type of the custom 
component.</p><p>In contrast, with Tapestry, <a  
href="component-classes.html">creating custom components</a> is a 
<em>beginner</em> topic: it is expected to be a daily activity for developers, 
because it is so easy. In fact, the steps are the same as creating a page. All 
you have to do is create a (potentially em
 pty) Java class in a "components" sub-package, and create a template file 
containing (X)HTML markup in the corresponding "components" sub-folder within 
your package hierarchy under /src/main/resources. You <em>use</em> a custom 
component just like you use any built-in Tapestry component: 
<code>&lt;t:mycomponent&gt;</code>.</p><p>Because they're so easy to create, 
Tapestry applications tend to have a lot of custom components and much less 
repetition of HTML than most JSF applications.</p><h2 
id="TapestryforJSFUsers-OtherReferences">Other References</h2><ul><li><a  
class="external-link" 
href="http://blog.tapestry5.de/wp-content/uploads/2010/06/JSF-2.0-vs-Tapestry-5.pdf";
 rel="nofollow">JavaServer Faces 2.0 vs. Tapestry 5: A Head-to-Head 
Comparison</a> slides by Igor Drobiazko, June 2010.</li><li><a  
class="external-link" 
href="http://docs.oracle.com/javaee/6/tutorial/doc/gkhxa.html"; 
rel="nofollow">Composite Components: Advanced Topics and Example</a> part of 
<em>The Java EE 6 Tutorial<
 /em> from Oracle</li></ul><p>&#160;</p><p></p></div>
       </div>
 
       <div class="clearer"></div>


Reply via email to