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 Wed Sep 20 
12:29:16 2017
@@ -27,6 +27,15 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
+    <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
+        <script>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -36,26 +45,13 @@
 
   <div class="wrapper bs">
 
-        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div>
-
-</div>
+        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div></div>
 
           <div id="top">
-            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";>
-  <input type="text" name="q">
-  <input type="submit" value="Search">
-</form>
-
-</div>
-
-
-<div class="emblem" style="float:left"><p><a  href="index.html"><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div>
-
-
-<div class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Tapestry for JSF Users</h1></div>
-
-</div>
+            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span><form 
enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";> 
+ <input type="text" name="q"> 
+ <input type="submit" value="Search"> 
+</form></div><div class="emblem" style="float:left"><p><a  
href="index.html"><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div><div
 class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Tapestry for JSF Users</h1></div></div>
       <div class="clearer"></div>
       </div>
 
@@ -67,34 +63,74 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p><parameter 
ac:name="hidden">true</parameter><parameter 
ac:name="atlassian-macro-output-type">INLINE</parameter><rich-text-body><p>a 
brief guide for learning Tapestry, designed for those who already know 
JavaServer Faces (JSF)</p></rich-text-body></p><p>&#160;</p><p>This is&#160;a 
brief guide for learning Tapestry, designed for those who already know 
JavaServer Faces (JSF).</p><p>Because both JSF and Tapestry are component 
oriented frameworks designed to serve mostly the same kinds of problems in 
similar ways, developers who already know JSF will find it very easy to learn 
Tapestry. In fact, Facelets, the default view technology in JSF 2.0, was 
created specifically to give JSF a Tapestry-like templating capability, so 
Facelets users should feel right at home.</p><parameter 
ac:name="style">float:right</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter 
ac:name="class">aui-label</parameter><rich-text-body><paramete
 r ac:name="showLabels">false</parameter><parameter 
ac:name="showSpace">false</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter ac:name="cql">label = "new-users" and space = 
currentSpace()</parameter></rich-text-body><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="conflue
 nceTh"><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:outp
 utRaw 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" 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; ta
 g</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
 col
 span="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="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" 
class="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/comp
 onents/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.htm
 l">&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/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/current/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/compon
 ents/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 cols
 pan="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" 
 >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 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><rich-text-body><rich-text-body><parameter 
ac:name="language">xml</parameter><parameter ac:name="title">JSF template 
(helloworld.xhtml)</parameter><plain-text-body>&lt;html 
xmlns="http://www.w3.org/1999/xhtml";
+                <div id="ConfluenceContent"><p>&#160;</p><p>This is&#160;a 
brief guide for learning Tapestry, designed for those who already know 
JavaServer Faces (JSF).</p><p>Because both JSF and Tapestry are component 
oriented frameworks designed to serve mostly the same kinds of problems in 
similar ways, developers who already know JSF will find it very easy to learn 
Tapestry. In fact, Facelets, the default view technology in JSF 2.0, was 
created specifically to give JSF a Tapestry-like templating capability, so 
Facelets users should feel right at home.</p><div class="aui-label" 
style="float:right" title="Related Articles"><h3>Related Articles</h3><ul 
class="content-by-label"><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="tapestry-for-jsf-users.html">Tapestry for JSF Users</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="tapestry-tutorial.html">Tapestry Tutorial</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="principles.html">Principles</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="getting-started.html">Getting Started</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="introduction.html">Introduction</a> 
+  </div> </li></ul></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="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 cols
 pan="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 Messag
 es</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" 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="confluence
 Th"><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="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" 
class="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" clas
 s="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 co
 lspan="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>T
 apestry</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/curr
 
ent/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/core
 lib/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="e
 xternal-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" rowspa
 n="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">
+<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;
     &lt;p&gt;&lt;h:outputText value="#{helloWorldBean.greeting} /&gt;&lt;/p&gt;
   &lt;/h:body&gt;
 &lt;/html&gt;
-</plain-text-body></rich-text-body><rich-text-body><parameter 
ac:name="language">xml</parameter><parameter ac:name="title">Tapestry template 
(HelloWorld.tml)</parameter><plain-text-body>&lt;html 
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"&gt;
+</pre>
+</div></div></div><div class="columnMacro"><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Tapestry template 
(HelloWorld.tml)</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;html 
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"&gt;
   &lt;body&gt;
     &lt;p&gt;${greeting}&lt;/p&gt;
   &lt;/body&gt;
 &lt;/html&gt;
-</plain-text-body></rich-text-body></rich-text-body><p>Though these are very 
similar, notice some differences:</p><ul><li>The #{...} syntax in JSF does not 
encode the underlying string, so you have to use the &lt;h:outputText&gt; tag 
if your data may contain HTML reserved characters such as &lt;, &gt;, or &amp;. 
In contrast, the ${...} syntax in Tapestry <strong>does</strong> encode the 
underlying string.</li><li>In JSF, backing beans are not necessarily related 
one-to-one with page templates. Often several templates use the same backing 
bean, and one template may reference multiple backing beans. In Tapestry, they 
are always related one-to-one, and therefore you don't have to specify which 
component class your ${...} expressions are 
referencing.</li></ul><rich-text-body><rich-text-body><parameter 
ac:name="language">java</parameter><parameter ac:name="title">JSF Backing Bean 
(HelloWorldBean.java)</parameter><plain-text-body>@ManagedBean
+</pre>
+</div></div></div></div></div></div><p>Though these are very similar, notice 
some differences:</p><ul><li>The #{...} syntax in JSF does not encode the 
underlying string, so you have to use the &lt;h:outputText&gt; tag if your data 
may contain HTML reserved characters such as &lt;, &gt;, or &amp;. In contrast, 
the ${...} syntax in Tapestry <strong>does</strong> encode the underlying 
string.</li><li>In JSF, backing beans are not necessarily related one-to-one 
with page templates. Often several templates use the same backing bean, and one 
template may reference multiple backing beans. In Tapestry, they are always 
related one-to-one, and therefore you don't have to specify which component 
class your ${...} expressions are referencing.</li></ul><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>J
 SF Backing Bean (HelloWorldBean.java)</b></div><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@ManagedBean
 @RequestScoped
 public class HelloWorldBean {
     public String getGreeting() {
         return "Hello, World!";
     }
 }
-</plain-text-body></rich-text-body><rich-text-body><parameter 
ac:name="language">java</parameter><parameter ac:name="title">Tapestry page 
class (HelloWorld.java)</parameter><plain-text-body>public class HelloWorld {
+</pre>
+</div></div></div><div class="columnMacro"><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Tapestry page class 
(HelloWorld.java)</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class HelloWorld {
     public String getGreeting() {
         return "Hello, World!";
     }
 }
-</plain-text-body></rich-text-body></rich-text-body><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="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="confluenceTd"><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 avaialble</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>${ [ user.name, 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-Eventha
 ndling">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><parameter ac:name="language">java</parameter><plain-text-body>public 
class Employee {
+</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="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="confluenc
 eTd"><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 c
 olspan="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 avaialble
 </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>${ [ user.name, 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 ha
 ndling</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;
-</plain-text-body><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 t
 o either make the values part of the page's <a  
href="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 e
 mpty) 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>
+</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="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 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 class="clearer"></div>

Modified: 
websites/production/tapestry/content/tapestry-inversion-of-control-faq.html
==============================================================================
--- websites/production/tapestry/content/tapestry-inversion-of-control-faq.html 
(original)
+++ websites/production/tapestry/content/tapestry-inversion-of-control-faq.html 
Wed Sep 20 12:29:16 2017
@@ -27,6 +27,16 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
+    <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
+        <script>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,7 +77,59 @@
       </div>
 
       <div id="content">
-                <div 
id="ConfluenceContent"><p><plain-text-body>{scrollbar}</plain-text-body></p><h2 
id="TapestryInversionofControlFAQ-TapestryInversionofControlContainer">Tapestry 
Inversion of Control Container</h2><p>Main article: <a  
href="ioc.html">Tapestry IoC</a></p><p>&#160;</p><parameter 
ac:name="style">float:right</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter 
ac:name="class">aui-label</parameter><rich-text-body><parameter 
ac:name="showLabels">false</parameter><parameter 
ac:name="showSpace">false</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter ac:name="cql">label = "ioc" and space = 
currentSpace()</parameter></rich-text-body><h3 
id="TapestryInversionofControlFAQ-WhydoIneedtodefineaninterfaceformyservices?Whycan'tIjustusetheclassitself?">Why
 do I need to define an interface for my services? Why can't I just use the 
class itself?</h3><p>First of all: you can do exactly this, but you lose some 
of the functionality that
  Tapestry's IoC container provides.</p><p>The reason for the split is so that 
Tapestry can provide functionality for your service around the core service 
implementation. It does this by creating <em>proxies</em>: Java classes that 
implement the service interface. The methods of the proxy will ultimately 
invoke the methods of your service implementation.</p><p>One of the primary 
purposes for proxies is to encapsulate the service's life cycle: most services 
are singletons that are created <em>just in time</em>. Just in time means only 
as soon as you invoke a method. What's going on is that the life cycle proxy 
(the object that gets injected into pages, components or other service 
implementations) checks on each method invocation to see if the actual service 
exists yet. If not, it instantiates and configures it (using proper locking to 
ensure thread safety), then delegates the method invocation to the 
service.</p><p>If you bind a service class (not a service interface and class), 
then 
 the service is fully instantiated the first time it is injected, rather than 
at that first method invocation. Further, you can't use decorations or method 
advice on such a service.</p><p>The final reason for the service interface / 
implementation split is to nudge you towards always coding to an interface, 
which has manifest benefits for code structure, robustness, and 
testability.</p><h3 
id="TapestryInversionofControlFAQ-Myservicestartsathread;howdoIknowwhentheapplicationisshuttingdown,tostopthatthread?">My
 service starts a thread; how do I know when the application is shutting down, 
to stop that thread?</h3><p>This same concern applies to any long-lived 
resource (a thread, a database connection, a JMS queue connection) that a 
service may hold onto. Your code needs to know when the application has been 
undeployed and shutdown. This is actually quite easy, by adding some 
post-injection logic to your implementation class.</p><parameter 
ac:name="controls">true</parameter><parameter ac
 :name="linenumbers">true</parameter><plain-text-body>public class 
MyServiceImpl implements MyService
+                <div id="ConfluenceContent"><h2 
id="TapestryInversionofControlFAQ-TapestryInversionofControlContainer">Tapestry 
Inversion of Control Container</h2><p>Main article: <a  
href="ioc.html">Tapestry IoC</a></p><p>&#160;</p><div class="aui-label" 
style="float:right" title="Related Articles">
+
+
+
+
+
+
+
+
+<h3>Related Articles</h3>
+
+<ul class="content-by-label"><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  href="ioc.html">IOC</a>
+                
+                        
+                    </div>
+    </li><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  href="ioc-cookbook.html">IoC cookbook</a>
+                
+                        
+                    </div>
+    </li><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  href="tapestry-ioc-overview.html">Tapestry IoC 
Overview</a>
+                
+                        
+                    </div>
+    </li><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+
+        <div class="details">
+                        <a  
href="tapestry-inversion-of-control-faq.html">Tapestry Inversion of Control 
FAQ</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div>
+
+
+<h3 
id="TapestryInversionofControlFAQ-WhydoIneedtodefineaninterfaceformyservices?Whycan'tIjustusetheclassitself?">Why
 do I need to define an interface for my services? Why can't I just use the 
class itself?</h3><p>First of all: you can do exactly this, but you lose some 
of the functionality that Tapestry's IoC container provides.</p><p>The reason 
for the split is so that Tapestry can provide functionality for your service 
around the core service implementation. It does this by creating 
<em>proxies</em>: Java classes that implement the service interface. The 
methods of the proxy will ultimately invoke the methods of your service 
implementation.</p><p>One of the primary purposes for proxies is to encapsulate 
the service's life cycle: most services are singletons that are created 
<em>just in time</em>. Just in time means only as soon as you invoke a method. 
What's going on is that the life cycle proxy (the object that gets injected 
into pages, components or other service implementation
 s) checks on each method invocation to see if the actual service exists yet. 
If not, it instantiates and configures it (using proper locking to ensure 
thread safety), then delegates the method invocation to the service.</p><p>If 
you bind a service class (not a service interface and class), then the service 
is fully instantiated the first time it is injected, rather than at that first 
method invocation. Further, you can't use decorations or method advice on such 
a service.</p><p>The final reason for the service interface / implementation 
split is to nudge you towards always coding to an interface, which has manifest 
benefits for code structure, robustness, and testability.</p><h3 
id="TapestryInversionofControlFAQ-Myservicestartsathread;howdoIknowwhentheapplicationisshuttingdown,tostopthatthread?">My
 service starts a thread; how do I know when the application is shutting down, 
to stop that thread?</h3><p>This same concern applies to any long-lived 
resource (a thread, a database connec
 tion, a JMS queue connection) that a service may hold onto. Your code needs to 
know when the application has been undeployed and shutdown. This is actually 
quite easy, by adding some post-injection logic to your implementation 
class.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: true; theme: Default" 
style="font-size:12px;">public class MyServiceImpl implements MyService
 {
   private boolean shuttingDown;
 
@@ -94,7 +156,8 @@
     });
   }
 }
-</plain-text-body><p>After Tapestry invokes the constructor of the service 
implementation, and after it performs any field injections, it invokes post 
injection methods. The methods must be public and return void. Parameters to a 
post injection method represent further injections ... in the above example, 
the RegistryShutdownHub is injected into the PostInjection method, since it is 
only used inside that one method.</p><rich-text-body><p>It is 
<strong>not</strong> recommended that MyServiceImpl take RegistryShutdownHub as 
a constructor parameter and register itself as a listener inside the 
constructor. Doing so is an example of <a  class="external-link" 
href="http://www.ibm.com/developerworks/java/library/j-jtp0618.html"; 
rel="nofollow">unsafe publishing</a>, a remote but potential thread safety 
issue.</p></rich-text-body><p>This same technique will work for any kind of 
resource that must be cleaned up or destroyed when the registry shuts 
down.</p><rich-text-body><p>Be careful not to
  invoke methods on any service proxy objects as they will also be shutting 
down with the Registry. A RegistryShutdownListener should not be reliant on 
anything outside of itself.</p></rich-text-body><h3 
id="TapestryInversionofControlFAQ-HowdoImakemyservicestartupwiththerestoftheapplication,ratherthanlazily?">How
 do I make my service startup with the rest of the application, rather than 
lazily?</h3><p>Tapestry services are designed to be <em>lazy</em>; they are 
only fully realized when needed: when the first method on the service interface 
is invoked.</p><p>Sometimes a service does extra work that is desirable at 
application startup: examples may be registering message handlers with a JMS 
implementation, or setting up indexing. Since the service's constructor (or <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/PostInjection.html";>@PostInjection</a>
 methods) are not invoked until the service is realized.</p><p>The solutio
 n is the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/EagerLoad.html";>@EagerLoad</a>
 annotation; service implementation classes marked with this annotation are 
loaded when the Registry is first startup, rather than 
lazily.<plain-text-body>{scrollbar}</plain-text-body></p></div>
+</pre>
+</div></div><p>After Tapestry invokes the constructor of the service 
implementation, and after it performs any field injections, it invokes post 
injection methods. The methods must be public and return void. Parameters to a 
post injection method represent further injections ... in the above example, 
the RegistryShutdownHub is injected into the PostInjection method, since it is 
only used inside that one method.</p><div class="confluence-information-macro 
confluence-information-macro-warning"><span class="aui-icon aui-icon-small 
aui-iconfont-error confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>It is <strong>not</strong> 
recommended that MyServiceImpl take RegistryShutdownHub as a constructor 
parameter and register itself as a listener inside the constructor. Doing so is 
an example of <a  class="external-link" 
href="http://www.ibm.com/developerworks/java/library/j-jtp0618.html"; 
rel="nofollow">unsafe publishing</a>, a remote but potential thr
 ead safety issue.</p></div></div><p>This same technique will work for any kind 
of resource that must be cleaned up or destroyed when the registry shuts 
down.</p><div class="confluence-information-macro 
confluence-information-macro-note"><span class="aui-icon aui-icon-small 
aui-iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Be careful not to invoke methods 
on any service proxy objects as they will also be shutting down with the 
Registry. A RegistryShutdownListener should not be reliant on anything outside 
of itself.</p></div></div><h3 
id="TapestryInversionofControlFAQ-HowdoImakemyservicestartupwiththerestoftheapplication,ratherthanlazily?">How
 do I make my service startup with the rest of the application, rather than 
lazily?</h3><p>Tapestry services are designed to be <em>lazy</em>; they are 
only fully realized when needed: when the first method on the service interface 
is invoked.</p><p>Sometimes a service does extra work
  that is desirable at application startup: examples may be registering message 
handlers with a JMS implementation, or setting up indexing. Since the service's 
constructor (or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/PostInjection.html";>@PostInjection</a>
 methods) are not invoked until the service is realized.</p><p>The solution is 
the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/EagerLoad.html";>@EagerLoad</a>
 annotation; service implementation classes marked with this annotation are 
loaded when the Registry is first startup, rather than lazily.</p></div>
       </div>
 
       <div class="clearer"></div>


Reply via email to