Modified: 
websites/production/tapestry/content/implementing-the-hi-lo-guessing-game.html
==============================================================================
--- 
websites/production/tapestry/content/implementing-the-hi-lo-guessing-game.html 
(original)
+++ 
websites/production/tapestry/content/implementing-the-hi-lo-guessing-game.html 
Sat Feb  3 13:21:04 2018
@@ -45,13 +45,26 @@
 
   <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">Implementing the Hi-Lo Guessing Game</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">Implementing the Hi-Lo Guessing Game</h1></div>
+
+</div>
       <div class="clearer"></div>
       </div>
 
@@ -63,7 +76,7 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p><span style="line-height: 
1.4285715;"><br clear="none"></span></p><p><span style="line-height: 
1.4285715;">Let's start building a basic Hi-Lo Guessing game.</span></p><p>In 
the game, the computer selects a number between 1 and 10. You try and guess the 
number, clicking links. At the end, the computer tells you how many guesses you 
required to identify the target number. Even a simple example like this will 
demonstrate several important concepts in Tapestry:</p><ul><li>Breaking an 
application into individual pages</li><li>Transferring information from one 
page to another</li><li>Responding to user interactions</li><li>Storing client 
information in the server-side session</li></ul><p>We'll build this little 
application in small pieces, using the kind of iterative development that 
Tapestry makes so easy.</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" 
src="implementing-the-hi-lo-guessing-game.dat
 a/hilo-flow.png"></span></p><p>Our page flow is very simple, consisting of 
three pages: Index (the starting page), Guess and GameOver. The Index page 
introduces the application and includes a link to start guessing. The Guess 
page presents the user with ten links, plus feedback such as "too low" or "too 
high". The GameOver page tells the user how many guesses they took before 
finding the target number.</p><h1 
id="ImplementingtheHi-LoGuessingGame-IndexPage">Index Page</h1><p>Let's get to 
work on the Index page and template. Make Index.tml look like this:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>Index.tml</b></div><div 
class="codeContent panelContent pdl">
+                <div id="ConfluenceContent"><p><span><br 
clear="none"></span></p><p><span>Let's start building a basic Hi-Lo Guessing 
game.</span></p><p>In the game, the computer selects a number between 1 and 10. 
You try and guess the number, clicking links. At the end, the computer tells 
you how many guesses you required to identify the target number. Even a simple 
example like this will demonstrate several important concepts in 
Tapestry:</p><ul><li>Breaking an application into individual 
pages</li><li>Transferring information from one page to 
another</li><li>Responding to user interactions</li><li>Storing client 
information in the server-side session</li></ul><p>We'll build this little 
application in small pieces, using the kind of iterative development that 
Tapestry makes so easy.</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/hilo
 -flow.png?version=2&amp;modificationDate=1286814202000&amp;api=v2" 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/hilo-flow.png?version=2&amp;modificationDate=1286814202000&amp;api=v2";></span></p><p>Our
 page flow is very simple, consisting of three pages: Index (the starting 
page), Guess and GameOver. The Index page introduces the application and 
includes a link to start guessing. The Guess page presents the user with ten 
links, plus feedback such as "too low" or "too high". The GameOver page tells 
the user how many guesses they took before finding the target number.</p><h1 
id="ImplementingtheHi-LoGuessingGame-IndexPage">Index Page</h1><p>Let's get to 
work on the Index page and template. Make Index.tml look like this:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>Index.tml</b></div><div 
class="codeContent panelContent pdl">
 <pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;html t:type="layout" title="Hi/Lo Guess"
     xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"&gt;
 
@@ -83,12 +96,12 @@ public class Index
 {
 }
 </pre>
-</div></div><p>Running the application gives us our start:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" 
src="implementing-the-hi-lo-guessing-game.data/hilo-1.png"></span></p><p>However,
 clicking the link doesn't do anything yet, as its just a placeholder &lt;a&gt; 
tag, not an actual Tapestry component. Let's think about what should happen 
when the user clicks that link:</p><ul><li>A random target number between 1 and 
10 should be selected</li><li>The number of guesses taken should be reset to 
0</li><li>The user should be sent to the Guess page to make a 
guess</li></ul><p>Our first step is to find out when the user clicks that 
"start guessing" link. In a typical web application framework, we might start 
thinking about URLs and handlers and maybe some sort of XML configuration file. 
But this is Tapestry, so we're going to work with components and methods on our 
classes.</p><p>First, the component. We want to perform an action (selecting t
 he number) before continuing on to the Guess page. The ActionLink component is 
just what we need; it creates a link with a URL that will trigger an action 
event in our code ... but that's getting ahead of ourselves. First up, convert 
the &lt;a&gt; tag to an ActionLink component:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Index.tml (partial)</b></div><div 
class="codeContent panelContent pdl">
+</div></div><p>Running the application gives us our start:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/hilo-1.png?version=3&amp;modificationDate=1416879474000&amp;api=v2";
 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/hilo-1.png?version=3&amp;modificationDate=1416879474000&amp;api=v2";></span></p><p>However,
 clicking the link doesn't do anything yet, as its just a placeholder &lt;a&gt; 
tag, not an actual Tapestry component. Let's think about what should happen 
when the user clicks that link:</p><ul><li>A random target number between 1 and 
10 should be selected</li><li>The number of guesses taken should be reset to 
0</li><li>The user should be sent to the Guess page to make a 
guess</li></ul><p>Our first step is to find out when the user clicks that 
"start guessing" link. In a typical web applica
 tion framework, we might start thinking about URLs and handlers and maybe some 
sort of XML configuration file. But this is Tapestry, so we're going to work 
with components and methods on our classes.</p><p>First, the component. We want 
to perform an action (selecting the number) before continuing on to the Guess 
page. The ActionLink component is just what we need; it creates a link with a 
URL that will trigger an action event in our code ... but that's getting ahead 
of ourselves. First up, convert the &lt;a&gt; tag to an ActionLink 
component:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Index.tml (partial)</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">    &lt;p&gt;
         &lt;t:actionlink t:id="start"&gt;start guessing&lt;/t:actionlink&gt;
     &lt;/p&gt;
 </pre>
-</div></div><p>If you refresh the browser and hover your mouse over the "start 
guessing" link, you'll see that its URL is now /tutorial1/index.start, which 
identifies the name of the page ("index") and the id of the component 
("start").</p><p>If you click the link now, you'll get an error:</p><p><span 
class="confluence-embedded-file-wrapper image-center-wrapper 
confluence-embedded-manual-size"><img class="confluence-embedded-image 
image-center" width="500" 
src="implementing-the-hi-lo-guessing-game.data/Application_Exception.png"></span></p><p>&#160;</p><p>Tapestry
 is telling us that we need to provide some kind of event handler for that 
event. What does that look like?</p><p>An event handler is a method of the Java 
class with a special name. The name is 
<code>on</code><strong><em>Eventname</em></strong><code>From</code><strong><em>Component-id</em></strong>
 ... here we want a method named <code>onActionFromStart()</code>. How do we 
know that "action" is the right event name? Because
  that's what ActionLink does, that's why its named 
<strong><em>Action</em></strong>Link.</p><p>Once again, Tapestry gives us 
options; if you don't like naming conventions, there's an @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/OnEvent.html";>OnEvent</a>
 annotation you can place on the method instead, which restores the freedom to 
name the method as you like. Details about this approach are in the <a  
href="component-events.html">Tapestry Users' Guide</a>. We'll be sticking with 
the naming convention approach for the tutorial.</p><p>When handling a 
component event request (the kind of request triggered by the ActionLink 
component's URL), Tapestry will find the component and trigger a component 
event on it. This is the callback our server-side code needs to figure out what 
the user is doing on the client side. Let's start with an empty event 
handler:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="co
 deHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Index.java</b></div><div class="codeContent panelContent pdl">
+</div></div><p>If you refresh the browser and hover your mouse over the "start 
guessing" link, you'll see that its URL is now /tutorial1/index.start, which 
identifies the name of the page ("index") and the id of the component 
("start").</p><p>If you click the link now, you'll get an error:</p><p><span 
class="confluence-embedded-file-wrapper image-center-wrapper 
confluence-embedded-manual-size"><img class="confluence-embedded-image 
confluence-external-resource image-center" width="500" 
src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/Application_Exception.png?version=1&amp;modificationDate=1428077959000&amp;api=v2";
 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/Application_Exception.png?version=1&amp;modificationDate=1428077959000&amp;api=v2";></span></p><p>&#160;</p><p>Tapestry
 is telling us that we need to provide some kind of event handler for that 
event. What does that look like?</p><p>An event handler is a method 
 of the Java class with a special name. The name is 
<code>on</code><strong><em>Eventname</em></strong><code>From</code><strong><em>Component-id</em></strong>
 ... here we want a method named <code>onActionFromStart()</code>. How do we 
know that "action" is the right event name? Because that's what ActionLink 
does, that's why its named <strong><em>Action</em></strong>Link.</p><p>Once 
again, Tapestry gives us options; if you don't like naming conventions, there's 
an @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/OnEvent.html";>OnEvent</a>
 annotation you can place on the method instead, which restores the freedom to 
name the method as you like. Details about this approach are in the <a  
href="implementing-the-hi-lo-guessing-game.html">Tapestry Users' Guide</a>. 
We'll be sticking with the naming convention approach for the 
tutorial.</p><p>When handling a component event request (the kind of request 
triggered by the ActionLink co
 mponent's URL), Tapestry will find the component and trigger a component event 
on it. This is the callback our server-side code needs to figure out what the 
user is doing on the client side. Let's start with an empty event 
handler:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Index.java</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">package com.example.tutorial1.pages;
 
 public class Index
@@ -154,7 +167,7 @@ public class Index
     }
 }
 </pre>
-</div></div><p>The new event handler method now chooses the target number, and 
tells the Guess page about it. Because Tapestry is a managed environment, we 
don't just create an instance of Guess ... it is Tapestry's responsibility to 
manage the life cycle of the Guess page. Instead, we ask Tapestry for the Guess 
page, using the @InjectPage annotation.</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>All fields in a Tapestry page or 
component class must be <strong>non-public</strong>.</p></div></div><p>Once we 
have that Guess page instance, we can invoke methods on it 
normally.</p><p>Returning a page instance from an event handler method directs 
Tapestry to send a client-side redirect to the returned page, rather than 
sending a redirect for the active page. Thus once the user clicks the "start 
guessing" lin
 k, they'll see the Guess page.</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>When creating your own 
applications, make sure that the objects stored in final variables are thread 
safe. It seems counter-intuitive, but final variables are shared across many 
threads. Ordinary instance variables are not. Fortunately, the implementation 
of Random is, in fact, thread safe.</p></div></div><p>So ... let's click the 
link and see what we get:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" 
src="implementing-the-hi-lo-guessing-game.data/guess-template-missing.png"></span></p><p>Ah!
 We didn't create a Guess page template. Tapestry was really expecting us to 
create one, so we better do so.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader pan
 elHeader pdl" style="border-bottom-width: 
1px;"><b>src/main/resources/com/example/tutorial/pages/Guess.tml</b></div><div 
class="codeContent panelContent pdl">
+</div></div><p>The new event handler method now chooses the target number, and 
tells the Guess page about it. Because Tapestry is a managed environment, we 
don't just create an instance of Guess ... it is Tapestry's responsibility to 
manage the life cycle of the Guess page. Instead, we ask Tapestry for the Guess 
page, using the @InjectPage annotation.</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>All fields in a Tapestry page or 
component class must be <strong>non-public</strong>.</p></div></div><p>Once we 
have that Guess page instance, we can invoke methods on it 
normally.</p><p>Returning a page instance from an event handler method directs 
Tapestry to send a client-side redirect to the returned page, rather than 
sending a redirect for the active page. Thus once the user clicks the "start 
guessing" lin
 k, they'll see the Guess page.</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>When creating your own 
applications, make sure that the objects stored in final variables are thread 
safe. It seems counter-intuitive, but final variables are shared across many 
threads. Ordinary instance variables are not. Fortunately, the implementation 
of Random is, in fact, thread safe.</p></div></div><p>So ... let's click the 
link and see what we get:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/guess-template-missing.png?version=2&amp;modificationDate=1416710821000&amp;api=v2";
 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/guess-tem
 
plate-missing.png?version=2&amp;modificationDate=1416710821000&amp;api=v2"></span></p><p>Ah!
 We didn't create a Guess page template. Tapestry was really expecting us to 
create one, so we better do so.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 
1px;"><b>src/main/resources/com/example/tutorial/pages/Guess.tml</b></div><div 
class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;html t:type="layout" title="Guess The Number"
     xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"&gt;
 
@@ -164,16 +177,16 @@ public class Index
   
 &lt;/html&gt;
 </pre>
-</div></div><p>Hit the browser's back button, then click the "start guessing" 
link again. We're getting closer:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" 
src="implementing-the-hi-lo-guessing-game.data/guess-no-target-prop.png"></span></p><p>If
 you scroll down, you'll see the line of the Guess.tml template that has the 
error. We have a field named target, but it is private and there's no 
corresponding property, so Tapestry was unable to access it.</p><p>We just need 
to write the missing JavaBeans accessor methods <code>getTarget()</code> (and 
<code>setTarget()</code> for good measure). Or we could let Tapestry write 
those methods instead:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+</div></div><p>Hit the browser's back button, then click the "start guessing" 
link again. We're getting closer:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/guess-no-target-prop.png?version=2&amp;modificationDate=1416711075000&amp;api=v2";
 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/guess-no-target-prop.png?version=2&amp;modificationDate=1416711075000&amp;api=v2";></span></p><p>If
 you scroll down, you'll see the line of the Guess.tml template that has the 
error. We have a field named target, but it is private and there's no 
corresponding property, so Tapestry was unable to access it.</p><p>We just need 
to write the missing JavaBeans accessor methods <code>getTarget()</code> (and 
<code>setTarget()</code> for good measure). Or we could let Tapestry write 
those methods instead:</p><div class="cod
 e panel pdl" style="border-width: 1px;"><div class="codeContent panelContent 
pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">    @Property
     private int target;
 </pre>
-</div></div><p>The @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Property.html";>Property</a>
 annotation very simply directs Tapestry to write the getter and setter method 
for you. You only need to do this if you are going to reference the field from 
the template.</p><p>We are getting very close but there's one last big oddity 
to handle. Once you refresh the page you'll see that target is 0!</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" 
src="implementing-the-hi-lo-guessing-game.data/guess-target-zero.png"></span></p><p>What
 gives? We know it was set to at least 1 ... where did the value go?</p><p>As 
noted above, Tapestry sends a redirect to the client after handling the event 
request. That means that the rendering of the page happens in an entirely new 
request. Meanwhile, at the end of each request, Tapestry wipes out the value in 
each instance variable. So that means that tar
 get <em>was</em> a non-zero number during the component event request ... but 
by the time the new page render request comes up from the web browser to render 
the Guess page, the value of the target field has reverted back to its default, 
zero.</p><p>The solution here is to mark which fields have values that should 
persist from one request to the next (and next, and next ...). That's what the 
@<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Persist.html";>Persist</a>
 annotation is for:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+</div></div><p>The @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Property.html";>Property</a>
 annotation very simply directs Tapestry to write the getter and setter method 
for you. You only need to do this if you are going to reference the field from 
the template.</p><p>We are getting very close but there's one last big oddity 
to handle. Once you refresh the page you'll see that target is 0!</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/guess-target-zero.png?version=3&amp;modificationDate=1416879255000&amp;api=v2";
 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/guess-target-zero.png?version=3&amp;modificationDate=1416879255000&amp;api=v2";></span></p><p>What
 gives? We know it was set to at least 1 ... where did the value go?</p><p>As no
 ted above, Tapestry sends a redirect to the client after handling the event 
request. That means that the rendering of the page happens in an entirely new 
request. Meanwhile, at the end of each request, Tapestry wipes out the value in 
each instance variable. So that means that target <em>was</em> a non-zero 
number during the component event request ... but by the time the new page 
render request comes up from the web browser to render the Guess page, the 
value of the target field has reverted back to its default, zero.</p><p>The 
solution here is to mark which fields have values that should persist from one 
request to the next (and next, and next ...). That's what the @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Persist.html";>Persist</a>
 annotation is for:</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;">    @Property  
     @Persist
     private int target;
 </pre>
-</div></div><p>This doesn't have anything to do with database persistence 
(that's coming up in a later chapter). It means that the value is stored in the 
HttpSession between requests.</p><p>Go back to the Index page and click the 
link again. Finally, we have a target number:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" 
src="implementing-the-hi-lo-guessing-game.data/guess-target.png"></span></p><p>That's
 enough for us to get started. Let's build out the Guess page, and get ready to 
let the user make guesses. We'll show the count of guesses, and increment that 
count when they make them. We'll worry about high and low and actually 
selecting the correct value later.</p><p>When building Tapestry pages, you 
sometimes start with the Java code and build the template to match, and 
sometime start with the template and build the Java code to match. Both 
approaches are valid. Here, lets start with the markup in the template, then 
figure out what we
  need in the Java code to make it work.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Guess.tml (revised)</b></div><div 
class="codeContent panelContent pdl">
+</div></div><p>This doesn't have anything to do with database persistence 
(that's coming up in a later chapter). It means that the value is stored in the 
HttpSession between requests.</p><p>Go back to the Index page and click the 
link again. Finally, we have a target number:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/guess-target.png?version=3&amp;modificationDate=1416879254000&amp;api=v2";
 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/guess-target.png?version=3&amp;modificationDate=1416879254000&amp;api=v2";></span></p><p>That's
 enough for us to get started. Let's build out the Guess page, and get ready to 
let the user make guesses. We'll show the count of guesses, and increment that 
count when they make them. We'll worry about high and low and actually 
selecting the correct value later.</p><
 p>When building Tapestry pages, you sometimes start with the Java code and 
build the template to match, and sometime start with the template and build the 
Java code to match. Both approaches are valid. Here, lets start with the markup 
in the template, then figure out what we need in the Java code to make it 
work.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Guess.tml (revised)</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;html t:type="layout" title="Guess The Number"
     xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd";
     xmlns:p="tapestry:parameter"&gt;
@@ -225,7 +238,7 @@ public class Guess
 
 }
 </pre>
-</div></div><p>The revised version of Guess includes two new properties: 
<code>current</code> and <code>guessCount</code>. There's also a handler for 
the action event from the makeGuess ActionLink component; currently it just 
increments the count.</p><p>Notice that the 
<code>onActionFromMakeGuess()</code> method now has a parameter: the context 
value that was encoded into the URL by the ActionLink. When then user clicks 
the link, Tapestry will automatically extract the string from the URL, convert 
it to an int and pass that int value into the event handler method. More 
boilerplate code you don't have to write.</p><p>At this point, the page is 
partially operational:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image" 
src="implementing-the-hi-lo-guessing-game.data/guess-1.png"></span></p><p>Our 
next step is to actually check the value provided by the user against the 
target and provide feedback: either they guessed too high, or too low, or just 
 right. If they get it just right, we'll switch to the GameOver page with a 
message such as "You guessed the number 5 in 2 guesses".</p><p>Let's start with 
the Guess page; it now needs a new property to store the message to be 
displayed to the user, and needs a field for the injected GameOver 
page:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Guess.java (partial)</b></div><div class="codeContent panelContent 
pdl">
+</div></div><p>The revised version of Guess includes two new properties: 
<code>current</code> and <code>guessCount</code>. There's also a handler for 
the action event from the makeGuess ActionLink component; currently it just 
increments the count.</p><p>Notice that the 
<code>onActionFromMakeGuess()</code> method now has a parameter: the context 
value that was encoded into the URL by the ActionLink. When then user clicks 
the link, Tapestry will automatically extract the string from the URL, convert 
it to an int and pass that int value into the event handler method. More 
boilerplate code you don't have to write.</p><p>At this point, the page is 
partially operational:</p><p><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/guess-1.png?version=4&amp;modificationDate=1416879255000&amp;api=v2";
 data-image-src="https://cwiki-test.apache.org/confluence/
 
download/attachments/23340505/guess-1.png?version=4&amp;modificationDate=1416879255000&amp;api=v2"></span></p><p>Our
 next step is to actually check the value provided by the user against the 
target and provide feedback: either they guessed too high, or too low, or just 
right. If they get it just right, we'll switch to the GameOver page with a 
message such as "You guessed the number 5 in 2 guesses".</p><p>Let's start with 
the Guess page; it now needs a new property to store the message to be 
displayed to the user, and needs a field for the injected GameOver 
page:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Guess.java (partial)</b></div><div class="codeContent panelContent 
pdl">
 <pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">    @Property
     @Persist(PersistenceConstants.FLASH)
     private String message;
@@ -293,7 +306,7 @@ public class GameOver
   
 &lt;/html&gt;
 </pre>
-</div></div><p>The result, when you guess correctly, should be 
this:</p><p><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image" 
src="implementing-the-hi-lo-guessing-game.data/gameover.png"></span></p><p>That 
wraps up the basics of Tapestry; we've demonstrated the basics of linking pages 
together and passing information from page to page in code as well as 
incorporating data inside URLs.</p><p>There's still more room to refactor this 
toy application; for example, making it possible to start a new game from the 
GameOver page (and doing it in a way that doesn't duplicate code). In addition, 
later we'll see other ways of sharing information between pages that are less 
cumbersome than the setup-and-persist approach shown here.</p><p>Next up: let's 
find out how Tapestry handles HTML forms and user input.</p><p>Next: <a  
href="using-beaneditform-to-create-user-forms.html">Using BeanEditForm To 
Create User Forms</a></p><p></p><p>&#160;</p><p>&#160;</p></div>
+</div></div><p>The result, when you guess correctly, should be 
this:</p><p><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image confluence-external-resource" 
src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/gameover.png?version=4&amp;modificationDate=1416879255000&amp;api=v2";
 
data-image-src="https://cwiki-test.apache.org/confluence/download/attachments/23340505/gameover.png?version=4&amp;modificationDate=1416879255000&amp;api=v2";></span></p><p>That
 wraps up the basics of Tapestry; we've demonstrated the basics of linking 
pages together and passing information from page to page in code as well as 
incorporating data inside URLs.</p><p>There's still more room to refactor this 
toy application; for example, making it possible to start a new game from the 
GameOver page (and doing it in a way that doesn't duplicate code). In addition, 
later we'll see other ways of sharing information between pages that are less 
cumbersome than the 
 setup-and-persist approach shown here.</p><p>Next up: let's find out how 
Tapestry handles HTML forms and user input.</p><p>Next: <a  
href="implementing-the-hi-lo-guessing-game.html">Implementing the Hi-Lo 
Guessing Game</a></p><p></p><p>&#160;</p><p>&#160;</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/introduction.html
==============================================================================
--- websites/production/tapestry/content/introduction.html (original)
+++ websites/production/tapestry/content/introduction.html Sat Feb  3 13:21:04 
2018
@@ -36,13 +36,26 @@
 
   <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">Introduction</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">Introduction</h1></div>
+
+</div>
       <div class="clearer"></div>
       </div>
 
@@ -54,37 +67,67 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><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><h2 id="Introduction-WhatisApacheTapestry?">What is 
Apache Tapestry?</h2><p>Apache Tapestry is an open-source framework for 
creating dynamic, robust, highly scalable web applications in Java. Tapestry 
complements and builds upon the standard Java Servlet API, and so it works in 
any servlet container or application server.</p><p>Tapestry divides a web 
application into a set of pages, each constructed from components. This 
provides a consistent structure, allowing the Tapestry framework to assume 
responsibility for key concerns such as URL construction and dispatch, 
persistent state storage on the client or on the server, user input validation, 
localization/internationalization, and exception reporting. Developing Tapestry 
applications involves creating HTML templates using plain HTML, and adding a 
small java class for each. In Tapestry, you create your application in terms of 
objects, and the methods and properties of those objects &#8211; and 
specifically no
 t in terms of URLs and query parameters. Tapestry brings true object oriented 
development to Java web applications.</p><p>Tapestry is specifically designed 
to make creating new components very easy, as this is a routine approach when 
building applications.</p><p>Tapestry is architected to scale from tiny, 
single-page applications all the way up to massive applications consisting of 
hundreds of individual pages, developed by large, diverse teams. Tapestry 
easily integrates with any kind of backend, including JEE, Spring and 
Hibernate.</p><p>It's more than what you can do with Tapestry ... it's also how 
you do it! Tapestry is a vastly productive environment. Java developers love it 
because they can make Java code changes and see them immediately ... no 
redeploy, no restart! And it's blazingly fast to boot (even when files have 
changed). Designers love it because Tapestry templates are so close to ordinary 
HTML, without all the cruft and confusion seen in <a  href="tapestry-for-jsf-use
 rs.html">JavaServer Pages</a>. Managers love it because it makes it easy for 
large teams to work together productively, and because they know important 
features (including localization) are baked right in. Once you work in Tapestry 
there's no going back!</p><p>Tapestry is released under the Apache Software 
License 2.0.</p><h2 
id="Introduction-ThirdPartyLibraries,TutorialsandResources">Third Party 
Libraries, Tutorials and Resources</h2><p>A number of third party libraries, 
tutorials and resources are listed on the <a  href="modules.html">Modules</a> 
page.</p><h2 id="Introduction-AboutReleasesandSnapshots">About Releases and 
Snapshots</h2><p>Most users will want to use the latest stable release of 
Tapestry, and for that your best bet for new projects is to use the Quickstart 
Maven archetype to create your initial Tapestry project, as described on the <a 
 href="getting-started.html">Getting Started</a> page. The Quickstart archetype 
generates a full, working project directory. For upgr
 ading existing projects, just use the Maven dependency listed on the <a  
href="download.html">Download</a> page.</p><p>You can also pull down Tapestry 
modules in the form of binary and source JARs from the <a  
class="external-link" href="http://search.maven.org/#browse"; title="1738327132" 
rel="nofollow">Maven Central repository</a>.</p><p>Tapestry itself is built 
using Gradle, which makes it really easy to download the source and build it 
yourself, either the whole project, or just one single module.</p><p>The use of 
Maven and Gradle has let us move with great speed, providing preview releases 
and snapshots.</p><p>Snapshots are intermediate versions of releases, with 
"-SNAPSHOT" at the end of the version number. Maven notices that -SNAPSHOT 
suffix and handles the dependency specially. It knows that snapshot releases 
can change frequently, so it will keep checking (at least once a day, maybe 
more often) to see if there's an updated version of the snapshot.</p><p>A 
nightly build proce
 ss on Tapestry's continuous integration server creates new snapshots every 
night.</p><p>Snapshots don't go in the Maven central repository (that's 
reserved for full releases). Instead, they go into the Tapestry snapshots 
repository at <a  class="external-link" 
href="https://repository.apache.org/content/groups/snapshots/org/apache/tapestry/";>https://repository.apache.org/content/groups/snapshots/org/apache/tapestry/</a>.</p><p>To
 access the snapshot repository, just add <code>-DremoteRepositories=<span 
class="nolink">http://repository.apache.org/snapshots/</span></code> to the 
command line when running Maven.</p><p>Documentation on this site sometimes 
refers to the latest snapshot ... that is, it is often ahead of the last 
official release, with version-specific differences clearly marked. In some 
cases, it is written as if the snapshot release is stable. For example, if 
documentation refers to version 5.4.x and that hasn't been released yet, you 
can try 5.4.x-SNAPSHOT.</p></div>
+                <div id="ConfluenceContent"><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>
+
+
+<h2 id="Introduction-WhatisApacheTapestry?">What is Apache 
Tapestry?</h2><p>Apache Tapestry is an open-source framework for creating 
dynamic, robust, highly scalable web applications in Java. Tapestry complements 
and builds upon the standard Java Servlet API, and so it works in any servlet 
container or application server.</p><p>Tapestry divides a web application into 
a set of pages, each constructed from components. This provides a consistent 
structure, allowing the Tapestry framework to assume responsibility for key 
concerns such as URL construction and dispatch, persistent state storage on the 
client or on the server, user input validation, 
localization/internationalization, and exception reporting. Developing Tapestry 
applications involves creating HTML templates using plain HTML, and adding a 
small java class for each. In Tapestry, you create your application in terms of 
objects, and the methods and properties of those objects &#8211; and 
specifically not in terms of URLs and qu
 ery parameters. Tapestry brings true object oriented development to Java web 
applications.</p><p>Tapestry is specifically designed to make creating new 
components very easy, as this is a routine approach when building 
applications.</p><p>Tapestry is architected to scale from tiny, single-page 
applications all the way up to massive applications consisting of hundreds of 
individual pages, developed by large, diverse teams. Tapestry easily integrates 
with any kind of backend, including JEE, Spring and Hibernate.</p><p>It's more 
than what you can do with Tapestry ... it's also how you do it! Tapestry is a 
vastly productive environment. Java developers love it because they can make 
Java code changes and see them immediately ... no redeploy, no restart! And 
it's blazingly fast to boot (even when files have changed). Designers love it 
because Tapestry templates are so close to ordinary HTML, without all the cruft 
and confusion seen in <a  href="introduction.html">JavaServer Pages</a>. Mana
 gers love it because it makes it easy for large teams to work together 
productively, and because they know important features (including localization) 
are baked right in. Once you work in Tapestry there's no going 
back!</p><p>Tapestry is released under the Apache Software License 2.0.</p><h2 
id="Introduction-ThirdPartyLibraries,TutorialsandResources">Third Party 
Libraries, Tutorials and Resources</h2><p>A number of third party libraries, 
tutorials and resources are listed on the <a  
href="introduction.html">Introduction</a> page.</p><h2 
id="Introduction-AboutReleasesandSnapshots">About Releases and 
Snapshots</h2><p>Most users will want to use the latest stable release of 
Tapestry, and for that your best bet for new projects is to use the Quickstart 
Maven archetype to create your initial Tapestry project, as described on the <a 
 href="introduction.html">Introduction</a> page. The Quickstart archetype 
generates a full, working project directory. For upgrading existing projects, 
just u
 se the Maven dependency listed on the <a  
href="introduction.html">Introduction</a> page.</p><p>You can also pull down 
Tapestry modules in the form of binary and source JARs from the <a  
class="external-link" href="http://search.maven.org/#browse"; rel="nofollow" 
title="1738327132">Maven Central repository</a>.</p><p>Tapestry itself is built 
using Gradle, which makes it really easy to download the source and build it 
yourself, either the whole project, or just one single module.</p><p>The use of 
Maven and Gradle has let us move with great speed, providing preview releases 
and snapshots.</p><p>Snapshots are intermediate versions of releases, with 
"-SNAPSHOT" at the end of the version number. Maven notices that -SNAPSHOT 
suffix and handles the dependency specially. It knows that snapshot releases 
can change frequently, so it will keep checking (at least once a day, maybe 
more often) to see if there's an updated version of the snapshot.</p><p>A 
nightly build process on Tapestry's contin
 uous integration server creates new snapshots every night.</p><p>Snapshots 
don't go in the Maven central repository (that's reserved for full releases). 
Instead, they go into the Tapestry snapshots repository at <a  
class="external-link" 
href="https://repository.apache.org/content/groups/snapshots/org/apache/tapestry/";>https://repository.apache.org/content/groups/snapshots/org/apache/tapestry/</a>.</p><p>To
 access the snapshot repository, just add <code>-DremoteRepositories=<span 
class="nolink"><a  class="external-link" 
href="http://repository.apache.org/snapshots/";>http://repository.apache.org/snapshots/</a></span></code>
 to the command line when running Maven.</p><p>Documentation on this site 
sometimes refers to the latest snapshot ... that is, it is often ahead of the 
last official release, with version-specific differences clearly marked. In 
some cases, it is written as if the snapshot release is stable. For example, if 
documentation refers to version 5.4.x and that hasn't been 
 released yet, you can try 5.4.x-SNAPSHOT.</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/principles.html
==============================================================================
--- websites/production/tapestry/content/principles.html (original)
+++ websites/production/tapestry/content/principles.html Sat Feb  3 13:21:04 
2018
@@ -44,13 +44,26 @@
 
   <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">Principles</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">Principles</h1></div>
+
+</div>
       <div class="clearer"></div>
       </div>
 
@@ -62,37 +75,67 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><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><h1 
id="Principles-Principle1&#8211;StaticStructure,DynamicBehavior">Principle 1 
&#8211; Static Structure, Dynamic Behavior</h1><p>The concept of "Dynamic 
Behavior" should be pretty obvious when you are building a web application; 
things should look different for different users/situations. But what does it 
mean that Tapestry has "Static Structure?" Static structure implies that when 
you build a page in Tapestry you are going to define all of the types of 
components that are used within that page. Under no circumstance during the 
rendering or event processing of the page will you be able to dynamically 
create a new type of component and place that into the component tree.</p><p>At 
first glance, this seems quite limiting ... other frameworks allow new elements 
to be created on the fly; it's also a common feature of desktop GUIs such as 
Swing. But static structure turns out to be not so limiting after all. You 
<em>can</em> create new elements (you're actually 
 re-rendering existing components with different properties). And you have 
plenty of options for getting dynamic behavior out of your static structure; 
from the simple conditional and looping components to the more advanced 
implementations of Tapestry's BeanEditor or Grid components, Tapestry gives you 
control over what renders and when, and even where it appears on the page. And 
starting in Tapestry 5.3 you can even use the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Dynamic.html";>Dynamic
 component</a>, which renders whatever is in an external template 
file.</p><p>Why did Tapestry choose static structure as a core principle? It's 
really a matter of meeting the requirements of agility and scalability.</p><h2 
id="Principles-Agility">Agility</h2><p>Tapestry is designed to be an agile 
working environment; "code less, deliver more". To support you writing less 
code Tapestry does a lot of work on your POJO pages and co
 mponents when first loading them. It also uses shared instances of page and 
component classes (shared across multiple threads and requests). Having 
dynamically modifiable structure would imply that each request has its own 
instance and, further, that the entire structure would need to be serialized 
between requests so that it can be restored to handle later 
requests.</p><p>Tapestry also makes you more agile by speeding up the 
development cycle with <a  href="class-reloading.html">Live Class 
Reloading</a>. Tapestry monitors the file system for changes to Java page 
classes, component classes, service implementation classes, HTML templates and 
component property files, and it hot-swaps the changes into the running 
application without requiring a restart <em>or losing session data</em>. This 
provides a very short code-save-view cycle that no other framework can 
touch.</p><h2 id="Principles-Scalability">Scalability</h2><p>When building 
large scale systems it is important to consider how 
 your resources are going to be used on each deployed server, and how that 
information is going to be shared between servers. Static structure means that 
page instances do not need to be stored inside the HttpSession and simple 
browsing users do not require extra system resources. This lean use of the 
HttpSession is key to Tapestry's very high scalability, especially in a 
clustered configuration. Again, linking an instance of a page to a particular 
client would require vastly more server-side resources than having a single 
shared page instance.</p><h1 
id="Principles-Principle2&#8211;AdaptiveAPI">Principle 2 &#8211; Adaptive 
API</h1><p>A key feature of Tapestry 5 is its adaptive API.</p><p>In 
traditional Java frameworks (including Struts, <a  
href="tapestry-for-jsf-users.html">JSF</a> and even the now-ancient Tapestry 4) 
user code is expected to conform to the framework. You create classes that 
extend from framework-provided base classes, or implement framework-provided 
interfaces.</p
 ><p>This works well until you upgrade to the next release of the framework: 
 >with the new features of the upgrade, you will more often than not experience 
 >breaks in backwards compatibility. Interfaces or base classes will have 
 >changed and your existing code will need to be changed to match.</p><p>In 
 >Tapestry 5, the framework adapts to your code. You have control over the 
 >names of the methods, the parameters they take, and the value that is 
 >returned. This is driven by annotations, which tell Tapestry under what 
 >circumstances your methods are to be invoked.</p><p>For example, you may have 
 >a login form and have a method that gets invoked when the form is 
 >submitted:</p><div class="code panel pdl" style="border-width: 1px;"><div 
 >class="codeContent panelContent pdl">
+                <div id="ConfluenceContent"><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>
+
+
+<h1 id="Principles-Principle1&#8211;StaticStructure,DynamicBehavior">Principle 
1 &#8211; Static Structure, Dynamic Behavior</h1><p>The concept of "Dynamic 
Behavior" should be pretty obvious when you are building a web application; 
things should look different for different users/situations. But what does it 
mean that Tapestry has "Static Structure?" Static structure implies that when 
you build a page in Tapestry you are going to define all of the types of 
components that are used within that page. Under no circumstance during the 
rendering or event processing of the page will you be able to dynamically 
create a new type of component and place that into the component tree.</p><p>At 
first glance, this seems quite limiting ... other frameworks allow new elements 
to be created on the fly; it's also a common feature of desktop GUIs such as 
Swing. But static structure turns out to be not so limiting after all. You 
<em>can</em> create new elements (you're actually re-rendering existing com
 ponents with different properties). And you have plenty of options for getting 
dynamic behavior out of your static structure; from the simple conditional and 
looping components to the more advanced implementations of Tapestry's 
BeanEditor or Grid components, Tapestry gives you control over what renders and 
when, and even where it appears on the page. And starting in Tapestry 5.3 you 
can even use the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Dynamic.html";>Dynamic
 component</a>, which renders whatever is in an external template 
file.</p><p>Why did Tapestry choose static structure as a core principle? It's 
really a matter of meeting the requirements of agility and scalability.</p><h2 
id="Principles-Agility">Agility</h2><p>Tapestry is designed to be an agile 
working environment; "code less, deliver more". To support you writing less 
code Tapestry does a lot of work on your POJO pages and components when first 
loadi
 ng them. It also uses shared instances of page and component classes (shared 
across multiple threads and requests). Having dynamically modifiable structure 
would imply that each request has its own instance and, further, that the 
entire structure would need to be serialized between requests so that it can be 
restored to handle later requests.</p><p>Tapestry also makes you more agile by 
speeding up the development cycle with <a  href="principles.html">Live Class 
Reloading</a>. Tapestry monitors the file system for changes to Java page 
classes, component classes, service implementation classes, HTML templates and 
component property files, and it hot-swaps the changes into the running 
application without requiring a restart <em>or losing session data</em>. This 
provides a very short code-save-view cycle that no other framework can 
touch.</p><h2 id="Principles-Scalability">Scalability</h2><p>When building 
large scale systems it is important to consider how your resources are going to 
be
  used on each deployed server, and how that information is going to be shared 
between servers. Static structure means that page instances do not need to be 
stored inside the HttpSession and simple browsing users do not require extra 
system resources. This lean use of the HttpSession is key to Tapestry's very 
high scalability, especially in a clustered configuration. Again, linking an 
instance of a page to a particular client would require vastly more server-side 
resources than having a single shared page instance.</p><h1 
id="Principles-Principle2&#8211;AdaptiveAPI">Principle 2 &#8211; Adaptive 
API</h1><p>A key feature of Tapestry 5 is its adaptive API.</p><p>In 
traditional Java frameworks (including Struts, <a  
href="principles.html">JSF</a> and even the now-ancient Tapestry 4) user code 
is expected to conform to the framework. You create classes that extend from 
framework-provided base classes, or implement framework-provided 
interfaces.</p><p>This works well until you upgrade to t
 he next release of the framework: with the new features of the upgrade, you 
will more often than not experience breaks in backwards compatibility. 
Interfaces or base classes will have changed and your existing code will need 
to be changed to match.</p><p>In Tapestry 5, the framework adapts to your code. 
You have control over the names of the methods, the parameters they take, and 
the value that is returned. This is driven by annotations, which tell Tapestry 
under what circumstances your methods are to be invoked.</p><p>For example, you 
may have a login form and have a method that gets invoked when the form is 
submitted:</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 Login
 {
   @Persist


Reply via email to