You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by bu...@apache.org on 2015/07/26 23:19:57 UTC

svn commit: r959684 [4/5] - in /websites/production/tapestry/content: ./ cache/

Modified: websites/production/tapestry/content/page-life-cycle.html
==============================================================================
--- websites/production/tapestry/content/page-life-cycle.html (original)
+++ websites/production/tapestry/content/page-life-cycle.html Sun Jul 26 21:19:56 2015
@@ -27,16 +27,6 @@
   </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 type="text/javascript">
-  SyntaxHighlighter.defaults['toolbar'] = false;
-  SyntaxHighlighter.all();
-  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,8 +57,73 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><h1 id="PageLifeCycle-PageLifeCycle">Page Life Cycle</h1><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
-<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div><p>In Tapestry, you are free to develop your presentation objects, page and components classes, as ordinary objects, complete with instance variables and so forth.</p><p>This is somewhat revolutionary in terms of web development in Java. Using traditional servlets, or Struts, your presentation objects (Servlets, or Struts Actions, or the equivalent in other frameworks) are <em>stateless singletons</em>. That is, a <em>single</em> instance is created, and all incoming requests are threaded through that single instance.</p><p>Because multiple requests are handled by many different threads, this means that the single instance's variable are useless ... any value written into an instance variable would immediately be overwritten by a different thread. Thus, it is necessary to use the Servlet API'
 s HttpServletRequest object to store per-request data, and the HttpSession object to store data between requests.</p><p>Tapestry takes a very different approach.</p><p>In Tapestry, each page is a singleton, but with a <em>per thread</em> map of field names &amp; values that Tapestry invisibly manages for you.</p><p>With this approach, all the difficult, ugly issues related to multi-threading go by the wayside. Instead, familiar, simple coding practices (using ordinary methods and fields) can be used.</p><div class="confluence-information-macro confluence-information-macro-information"><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Tapestry 5.0 and 5.1 used page pooling, rather than a singleton page with a per_thread map, to achieve the same effect.</p></div></div><h2 id="PageLifeCycle-PageLifeCycleMethods">Page Life Cycle Methods</h2><p>There are a few situations where it is useful fo
 r a component to perform some operations, usually some kind of initialization or caching, based on the life cycle of the page.</p><p>The page life cycle is quite simple. When first needed, a page is loaded. Loading a page involves instantiating the components of the page and connecting them together.</p><p>Once a page is loaded, it is <em>attached</em> to the current request. Remember that there will be many threads, each handling its own request to the same page.</p><p>At the end of a request, after a response has been sent to the client, the page is <em>detached</em> from the request. This is a chance to perform any cleanup needed for the page.</p><p>As with <a shape="rect" href="component-rendering.html">component rendering</a>, you have the ability to make your components "aware" of these events by identifying methods to be invoked.</p><p>Page life cycle methods should take no parameters and return void.</p><p>You have the choice of attaching an annotation to a method, or simply
  using the method naming conventions:</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Annotation</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Method Name</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>When Called</p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>@<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageLoaded.html">PageLoaded</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>pageLoaded()</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>After the page is fully loaded</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>@<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageAttached.html">PageAttached</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>pageAttache
 d()</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>After the page is attached to the request.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>@<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageDetached.html">PageDetached</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>pageDetached()</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>AFter the page is detached from the request.</p></td></tr></tbody></table></div><h2 id="PageLifeCycle-ComparisontoJavaServerPages">Comparison to JavaServer Pages</h2><p>JSPs also act as singletons. However, the individual JSP tags are pooled.</p><p>This is one of the areas where Tapestry can significantly outperform JSPs. Much of the code inside a compiled JSP class concerns getting tags from a tag pool, configuring the properties of the tag instance, using the tag instance, then cleaning up the tag instance and putting it 
 back in the pool.</p><p>The operations Tapestry does once per request are instead executed dozens or potentially hundreds of times (depending the complexity of the page, and if any nested loops occur).</p><p>Pooling JSP tags is simply the wrong granularity.</p><p>Tapestry can also take advantage of its more coarse grained caching to optimize how data moves, via parameters, between components. This means that Tapestry pages will actually speed up after they render the first time.</p><h2 id="PageLifeCycle-PagePoolConfiguration">Page Pool Configuration</h2><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>This related to versions of Tapestry prior to 5.2. Modern Tapestry uses an alternate approach that allows a single page instance to be shared across many request processing threads.</p></div></div><p>In Tapestry
  5.0 and 5.1, a page pool is used to store page instances. The pool is "keyed" on the name of the page (such as "start") and the <em>locale</em> for the page (such as "en" or "fr").</p><p>Within each key, Tapestry tracks the number of page instances that have been created, as well as the number that are in use (currently attached to a request).</p><p>When a page is first accessed in a request, it is taken from the pool. Tapestry has some <a shape="rect" href="configuration.html">configuration values</a> that control the details of how and when page instances are created.</p><ul><li>If a free page instance is available, the page is marked in use and attached to the request.</li><li>If there are fewer page instances than the <em>soft limit</em>, then a new page instance is simply created and attached to the request.</li><li>If the soft limit has been reached, Tapestry will wait for a short period of time for a page instance to become available before creating a new page instance.</li>
 <li>If the hard limit has been reached, Tapestry will throw an exception rather than create a new page instance.</li><li>Otherwise, Tapestry will create a new page instance.<br clear="none"> Thus a busy application will initially create pages up-to the soft limit (which defaults to five page instances). If the application continues to be pounded with requests, it will slow its request processing, using the soft wait time in an attempt to reuse an existing page instance.</li></ul><p>A truly busy application will continue to create new page instances as needed until the hard limit is reached.</p><p>Remember that all these configuration values are per key: the combination of page name and locale. Thus even with a hard limit of 20, you may eventually find that Tapestry has created 20 start page instances for locale "en" <em>and</em> 20 start page instances for locale "fr" (if your application is configured to support both English and French). Likewise, you may have 20 instances for the 
 start page, and 20 instances for the newaccount page.</p><p>Tapestry periodically checks its cache for page instances that have not been used recently (within a configurable window). Unused page instances are release to the garbage collector.</p><p>The end result is that you have quite a degree of tuning control over the process. If memory is a limitation and throughput can be sacrificed, try lowering the soft and hard limit and increasing the soft wait.</p><p>If performance is absolute and you have lots of memory, then increase the soft and hard limit and reduce the soft wait. This encourages Tapestry to create more page instances and not wait as long to re-use existing instances.</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 shape="rect" href="page-navigation.html">Page Navigation</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 shape="rect" href="page-life-cycle.html">Page Life Cycle</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 shape="rect" href="component-rendering.html">Component Rendering</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 shape="rect" href="component-events.html">Component Events</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 shape="rect" href="component-events-faq.html">Component Events FAQ</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 shape="rect" href="request-processing.html">Request Processing</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div><p>In Tapestry, you are free to develop your presentation objects, page and components classes, as ordinary objects, complete with instance variables and so forth.</p><p>This is somewhat revolutionary in terms of web development in Java. Using traditional servlets, or Struts, your presentation objects (Servlets, or Struts Actions, or the equivalent in other frameworks) are <em>stateless singletons</em>. That is, a <em>single</em> instance is created, and all incoming requests are threaded through that single instance.</p><p>Because multiple requests are handled by many different threads, this means that the single instance's variable are useless ... any value written into an instance variable would immediately be overwritten by a different thread. Thus, it is necessary to use the Servlet API's HttpServletRequest object to store per-request data, and the HttpSession object to store data between requests.</p><p>Tapestry takes a very different approach.</p><p>In Tapestry, each pa
 ge is a singleton, but with a <em>per thread</em> map of field names &amp; values that Tapestry invisibly manages for you.</p><p>With this approach, all the difficult, ugly issues related to multi-threading go by the wayside. Instead, familiar, simple coding practices (using ordinary methods and fields) can be used.</p><div class="confluence-information-macro confluence-information-macro-information"><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Tapestry 5.0 and 5.1 used page pooling, rather than a singleton page with a per_thread map, to achieve the same effect.</p></div></div><h2 id="PageLifeCycle-PageLifeCycleMethods">Page Life Cycle Methods</h2><p>There are a few situations where it is useful for a component to perform some operations, usually some kind of initialization or caching, based on the life cycle of the page.</p><p>The page life cycle is quite simple. When first needed,
  a page is loaded. Loading a page involves instantiating the components of the page and connecting them together.</p><p>Once a page is loaded, it is <em>attached</em> to the current request. Remember that there will be many threads, each handling its own request to the same page.</p><p>At the end of a request, after a response has been sent to the client, the page is <em>detached</em> from the request. This is a chance to perform any cleanup needed for the page.</p><p>As with <a shape="rect" href="component-rendering.html">component rendering</a>, you have the ability to make your components "aware" of these events by identifying methods to be invoked.</p><p>Page life cycle methods should take no parameters and return void.</p><p>You have the choice of attaching an annotation to a method, or simply using the method naming conventions:</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Annotation</p></th><th colspa
 n="1" rowspan="1" class="confluenceTh"><p>Method Name</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>When Called</p></th></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>@<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageLoaded.html">PageLoaded</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>pageLoaded()</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>After the page is fully loaded</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>@<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageAttached.html">PageAttached</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>pageAttached()</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>After the page is attached to the request.</p></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>@<a shape="r
 ect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/PageDetached.html">PageDetached</a></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>pageDetached()</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>AFter the page is detached from the request.</p></td></tr></tbody></table></div><h2 id="PageLifeCycle-ComparisontoJavaServerPages">Comparison to JavaServer Pages</h2><p>JSPs also act as singletons. However, the individual JSP tags are pooled.</p><p>This is one of the areas where Tapestry can significantly outperform JSPs. Much of the code inside a compiled JSP class concerns getting tags from a tag pool, configuring the properties of the tag instance, using the tag instance, then cleaning up the tag instance and putting it back in the pool.</p><p>The operations Tapestry does once per request are instead executed dozens or potentially hundreds of times (depending the complexity of the page, and if any nested 
 loops occur).</p><p>Pooling JSP tags is simply the wrong granularity.</p><p>Tapestry can also take advantage of its more coarse grained caching to optimize how data moves, via parameters, between components. This means that Tapestry pages will actually speed up after they render the first time.</p><h2 id="PageLifeCycle-PagePoolConfiguration">Page Pool Configuration</h2><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>This related to versions of Tapestry prior to 5.2. Modern Tapestry uses an alternate approach that allows a single page instance to be shared across many request processing threads.</p></div></div><p>In Tapestry 5.0 and 5.1, a page pool is used to store page instances. The pool is "keyed" on the name of the page (such as "start") and the <em>locale</em> for the page (such as "en" or "fr").</p><p>
 Within each key, Tapestry tracks the number of page instances that have been created, as well as the number that are in use (currently attached to a request).</p><p>When a page is first accessed in a request, it is taken from the pool. Tapestry has some <a shape="rect" href="configuration.html">configuration values</a> that control the details of how and when page instances are created.</p><ul><li>If a free page instance is available, the page is marked in use and attached to the request.</li><li>If there are fewer page instances than the <em>soft limit</em>, then a new page instance is simply created and attached to the request.</li><li>If the soft limit has been reached, Tapestry will wait for a short period of time for a page instance to become available before creating a new page instance.</li><li>If the hard limit has been reached, Tapestry will throw an exception rather than create a new page instance.</li><li>Otherwise, Tapestry will create a new page instance.<br clear="none
 "> Thus a busy application will initially create pages up-to the soft limit (which defaults to five page instances). If the application continues to be pounded with requests, it will slow its request processing, using the soft wait time in an attempt to reuse an existing page instance.</li></ul><p>A truly busy application will continue to create new page instances as needed until the hard limit is reached.</p><p>Remember that all these configuration values are per key: the combination of page name and locale. Thus even with a hard limit of 20, you may eventually find that Tapestry has created 20 start page instances for locale "en" <em>and</em> 20 start page instances for locale "fr" (if your application is configured to support both English and French). Likewise, you may have 20 instances for the start page, and 20 instances for the newaccount page.</p><p>Tapestry periodically checks its cache for page instances that have not been used recently (within a configurable window). Unuse
 d page instances are release to the garbage collector.</p><p>The end result is that you have quite a degree of tuning control over the process. If memory is a limitation and throughput can be sacrificed, try lowering the soft and hard limit and increasing the soft wait.</p><p>If performance is absolute and you have lots of memory, then increase the soft and hard limit and reduce the soft wait. This encourages Tapestry to create more page instances and not wait as long to re-use existing instances.</p></div>
 </div>
 
 <div class="clearer"></div>

Modified: websites/production/tapestry/content/page-navigation.html
==============================================================================
--- websites/production/tapestry/content/page-navigation.html (original)
+++ websites/production/tapestry/content/page-navigation.html Sun Jul 26 21:19:56 2015
@@ -67,8 +67,82 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><h1 id="PageNavigation-PageNavigation">Page Navigation</h1><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
-<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div><p>In essence, a Tapestry application is a number of related pages, working together. To some degree, each page is like an application unto itself.</p><p>Any individual request will be targeted at a single page. Requests come in two forms:&#160;</p><ul><li><em>component event</em> requests target a specific component on a specific page, triggering an event within that component</li><li><em>render</em> requests target a specific page, and stream the HTML markup for that page back to the client</li></ul><p>This dichotomy between component event requests and render requests alleviates a number of problems in traditional web applications related to the browser back button, or to the user hitting the refresh button in their browser.</p><p><br clear="none"><span style="color: rgb(83,145,38);font-si
 ze: 20.0px;line-height: 1.5;">Logical Page Name Shortening</span></p><p>In certain cases, Tapestry will shorten the the logical name of a page. For example, the page class org.example.pages.address.CreateAddress will be given a logical name of "address/Create" (the redundant "Address" is removed as a suffix). However, this only affects how the page is referenced in URLs; the template file will still be CreateAddress.tml, whether on the classpath, or as address/CreateAddress.tml (in the web context).</p><p><span>Tapestry actually creates multiple names for the name page: "address/Create" and "address/CreateAddress" are both synonymous. You can user either in Java code that refers to a page by name, or as the page parameter of a PageLink.</span></p><h2 id="PageNavigation-ComponentEventRequests&amp;Responses">Component Event Requests &amp; Responses</h2><p>Main Article: <a shape="rect" href="component-events.html">Component Events</a></p><p>Component event requests may take the form of
  hyperlinks (<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/EventLink.html">EventLink</a> or <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html">ActionLink</a>) or form submissions (<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html">Form</a>).</p><p>The value returned from an <a shape="rect" href="component-events.html">event handler method</a> controls the response sent to the client web browser.</p><p>The URL for a component event request identifies the name of the page, the nested id of the component, and the name of the event to trigger on the component (this is usually "action"). Further, a component event request may contain additional context information, which will be provided to the event handler method.</p><p>These URL
 s expose a bit of the internal structure of the application. Over time, as an application grows and is maintained, the ids of components may change. This means that component event request URLs should not be bookmarked. Fortunately, users will rarely have the chance to do so (see below).</p><h3 id="PageNavigation-1.Nullresponse">1. Null response</h3><p>If the event handler method returns no value, or returns null, then the current page (the page containing the component) will render the response.</p><p>A page render link for the current page is created and sent to the client as a client side redirect. The client browser will automatically submit a new request to generate the page.</p><p>The user will see the newly generated content in their browser. In addition, the URL in the browser's address bar will be a render request URL. Render request URLs are shorter and contain less application structure (for instance, they don't include component ids or event types). Render requests URLs 
 are what your users will bookmark. The component event request URLs are transitory, meaningful only while the application is actively engaged, and not meant to be used in later sessions.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<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 shape="rect" href="content-type-and-markup.html">Content Type and Markup</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 shape="rect" href="page-navigation.html">Page Navigation</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 shape="rect" href="page-life-cycle.html">Page Life Cycle</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 shape="rect" href="component-rendering.html">Component Rendering</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 shape="rect" href="component-events.html">Component Events</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 shape="rect" href="component-events-faq.html">Component Events FAQ</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 shape="rect" href="request-processing.html">Request Processing</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div><p>In essence, a Tapestry application is a number of related pages, working together. To some degree, each page is like an application unto itself.</p><p>Any individual request will be targeted at a single page. Requests come in two forms:&#160;</p><ul><li><em>component event</em> requests target a specific component on a specific page, triggering an event within that component</li><li><em>render</em> requests target a specific page, and stream the HTML markup for that page back to the client</li></ul><p>This dichotomy between component event requests and render requests alleviates a number of problems in traditional web applications related to the browser back button, or to the user hitting the refresh button in their browser.</p><p><br clear="none"><span style="color: rgb(83,145,38);font-size: 20.0px;line-height: 1.5;">Logical Page Name Shortening</span></p><p>In certain cases, Tapestry will shorten the the logical name of a page. For example, the page class org.example.page
 s.address.CreateAddress will be given a logical name of "address/Create" (the redundant "Address" is removed as a suffix). However, this only affects how the page is referenced in URLs; the template file will still be CreateAddress.tml, whether on the classpath, or as address/CreateAddress.tml (in the web context).</p><p><span>Tapestry actually creates multiple names for the name page: "address/Create" and "address/CreateAddress" are both synonymous. You can user either in Java code that refers to a page by name, or as the page parameter of a PageLink.</span></p><h2 id="PageNavigation-ComponentEventRequests&amp;Responses">Component Event Requests &amp; Responses</h2><p>Main Article: <a shape="rect" href="component-events.html">Component Events</a></p><p>Component event requests may take the form of hyperlinks (<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/EventLink.html">EventLink</a> or <a shape="rect"
  class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html">ActionLink</a>) or form submissions (<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html">Form</a>).</p><p>The value returned from an <a shape="rect" href="component-events.html">event handler method</a> controls the response sent to the client web browser.</p><p>The URL for a component event request identifies the name of the page, the nested id of the component, and the name of the event to trigger on the component (this is usually "action"). Further, a component event request may contain additional context information, which will be provided to the event handler method.</p><p>These URLs expose a bit of the internal structure of the application. Over time, as an application grows and is maintained, the ids of components may change. This means that component event request
  URLs should not be bookmarked. Fortunately, users will rarely have the chance to do so (see below).</p><h3 id="PageNavigation-1.Nullresponse">1. Null response</h3><p>If the event handler method returns no value, or returns null, then the current page (the page containing the component) will render the response.</p><p>A page render link for the current page is created and sent to the client as a client side redirect. The client browser will automatically submit a new request to generate the page.</p><p>The user will see the newly generated content in their browser. In addition, the URL in the browser's address bar will be a render request URL. Render request URLs are shorter and contain less application structure (for instance, they don't include component ids or event types). Render requests URLs are what your users will bookmark. The component event request URLs are transitory, meaningful only while the application is actively engaged, and not meant to be used in later sessions.</
 p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">public Object onAction(){
   return null;
 }</pre>
@@ -104,7 +178,7 @@ public Object onAction(){
 </div></div><p>The activation context may consist of a series of values, in which case the return value of the method should be an array or a List.</p><div class="confluence-information-macro confluence-information-macro-information"><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Note: If you are using the <a shape="rect" href="hibernate-user-guide.html">tapestry-hibernate</a> integration library and your passivate context is a Hibernate entity, then you can just use the entity itself, not its id. Tapestry will automatically extract the entity's id into the URL, and convert it back for the "activate" event handler method.</p></div></div><h2 id="PageNavigation-Pageactivation">Page activation</h2><p>When a page render request arrives, the page is activated before it is rendered.</p><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:0 1em">
 <p>    <strong>JumpStart Demos:</strong><br clear="none">
     <a shape="rect" class="external-link" href="http://jumpstart.doublenegative.com.au/jumpstart/examples/navigation/onactivateandonpassivate/3" >onActivate and onPassivate</a><br clear="none">
-    <a shape="rect" class="external-link" href="http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/handlingabadcontext/1" >Handling A Bad Context</a></p></div><p>Activation serves two purposes:</p><ul><li>It allows the page to restore its internal state from data encoded into the URL (the activation context discussed above).</li><li>It provides coarse approach to validating access to the page.<br clear="none"> The later case, validation, is generally concerned with user identity and access; if you have pages that may only be accessed by certain users, you may use the page's activate event handler responsible for verifying that access.</li></ul><p>A page's activate event handler mirrors its passivate handler:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+    <a shape="rect" class="external-link" href="http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/handlingabadcontext/1" >Handling A Bad Context</a></p></div>Activation serves two purposes:<ul><li>It allows the page to restore its internal state from data encoded into the URL (the activation context discussed above).</li><li>It provides coarse approach to validating access to the page.<br clear="none"> The later case, validation, is generally concerned with user identity and access; if you have pages that may only be accessed by certain users, you may use the page's activate event handler responsible for verifying that access.</li></ul><p>A page's activate event handler mirrors its passivate handler:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">  . . .
 
   void onActivate(long productId)

Modified: websites/production/tapestry/content/parameter-type-coercion.html
==============================================================================
--- websites/production/tapestry/content/parameter-type-coercion.html (original)
+++ websites/production/tapestry/content/parameter-type-coercion.html Sun Jul 26 21:19:56 2015
@@ -31,8 +31,6 @@
   <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 type="text/javascript">
   SyntaxHighlighter.defaults['toolbar'] = false;
   SyntaxHighlighter.all();
@@ -67,9 +65,73 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><p><strong style="text-align: justify;">Type Coercion</strong><span style="color: rgb(0,0,0);">&#160;is the conversion of one type of object to a new object of a different type with similar content. Tapestry frequently must coerce objects from one type to another. A common example is the coercion of a string into an integer or a double.</span></p><p>See&#160;<a shape="rect" href="type-coercion.html">Type Coercer Service</a> for the list of build-in coercions.</p><h2 id="ParameterTypeCoercion-ParameterTypeCoercions">Parameter Type Coercions</h2><div class="navmenu" style="float:right; background:white; margin:3px; padding:3px">
-<div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px"></div>
-<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div><p>Tapestry automatically handles type coercions for <a shape="rect" href="component-parameters.html">component parameters</a>.</p><p>Type coercions occur when a value passed into a parameter (as bound in a template or in an annotation) does not match the type of the parameter.</p><p>For example, consider the Count component:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<div id="ConfluenceContent"><p><strong style="text-align: justify;">Type Coercion</strong><span style="color: rgb(0,0,0);">&#160;is the conversion of one type of object to a new object of a different type with similar content. Tapestry frequently must coerce objects from one type to another. A common example is the coercion of a string into an integer or a double.</span></p><p>See&#160;<a shape="rect" href="type-coercion.html">Type Coercer Service</a> for the list of build-in coercions.</p><h2 id="ParameterTypeCoercion-ParameterTypeCoercions">Parameter Type Coercions</h2><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 shape="rect" href="type-coercion.html">Type Coercion</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 shape="rect" href="parameter-type-coercion.html">Parameter Type Coercion</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 shape="rect" href="enum-parameter-recipe.html">Enum Parameter Recipe</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 shape="rect" href="supporting-informal-parameters.html">Supporting Informal Parameters</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 shape="rect" href="default-parameter.html">Default Parameter</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 shape="rect" href="component-parameters.html">Component Parameters</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div><p>Tapestry automatically handles type coercions for <a shape="rect" href="component-parameters.html">component parameters</a>.</p><p>Type coercions occur when a value passed into a parameter (as bound in a template or in an annotation) does not match the type of the parameter.</p><p>For example, consider the Count component:</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 Count
 {
     @Parameter

Modified: websites/production/tapestry/content/persistent-page-data.html
==============================================================================
--- websites/production/tapestry/content/persistent-page-data.html (original)
+++ websites/production/tapestry/content/persistent-page-data.html Sun Jul 26 21:19:56 2015
@@ -67,15 +67,53 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><p>&#160;</p><h1 id="PersistentPageData-PersistentPageData">Persistent Page Data</h1><div class="confluence-information-macro confluence-information-macro-information"><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>The use of the term "persistence" here refers to <em>page-level</em> persistence, NOT database persistence.</p></div></div><p>Most instance variables in Tapestry are automatically cleared at the end of each request. This is important, as it pertains to how Tapestry pages are shared, over time, by many users.</p><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
-<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div><p>However, you often want to store some data on a <em>single</em> page, and have access to it in later requests to that same page, without having to store it in a database between requests. (To store values across multiple pages, see <a shape="rect" href="session-storage.html">Session Storage</a>.)</p><p>Making page data persist across requests to a single page is accomplished with the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Persist.html">Persist</a> annotation. This annotation is applied to private instance fields of components:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<div id="ConfluenceContent"><div class="confluence-information-macro confluence-information-macro-information"><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>The use of the term "persistence" here refers to <em>page-level</em> persistence, NOT database persistence.</p></div></div><p>Most instance variables in Tapestry are automatically cleared at the end of each request. This is important, as it pertains to how Tapestry pages are shared, over time, by many users.</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 shape="rect" href="performance-and-clustering.html">Performance and Clustering</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 shape="rect" href="session-storage.html">Session Storage</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 shape="rect" href="persistent-page-data.html">Persistent Page Data</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div><p>However, you often want to store some data on a <em>single</em> page, and have access to it in later requests to that same page, without having to store it in a database between requests. (To store values across multiple pages, see <a shape="rect" href="session-storage.html">Session Storage</a>.)</p><p>Making page data persist across requests to a single page is accomplished with the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Persist.html">Persist</a> annotation. This annotation is applied to private instance fields of components:</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;">  @Persist
   private int value;
 </pre>
-</div></div><p>Such annotated fields will retain their state between requests. Generally, speaking, this means that the value is stored into the session (but other approaches are possible).</p><p>Whenever you make a change to a persistent field, its value is saved. On later requests to the same page, the value for the field is restored.</p><h2 id="PersistentPageData-PersistenceStrategies">Persistence Strategies</h2><p>The value for each field is the <em>strategy</em> used to store the field between requests.</p><h3 id="PersistentPageData-SessionStrategy">Session Strategy</h3><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:0 1em">
+</div></div><p>Such annotated fields will retain their state between requests. Generally, speaking, this means that the value is stored into the session (but other approaches are possible).</p><p>Whenever you make a change to a persistent field, its value is saved. On later requests to the same page, the value for the field is restored.</p><h2 id="PersistentPageData-PersistenceStrategies">Persistence Strategies</h2><p>The value for each field is the <em>strategy</em> used to store the field between requests.</p><h3 id="PersistentPageData-SessionStrategy">Session Strategy</h3><p></p><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:0 1em">
 <p>    <strong>JumpStart Demo:</strong><br clear="none">
     <a shape="rect" class="external-link" href="http://jumpstart.doublenegative.com.au/jumpstart/examples/state/storingdatainapage" >Storing Data in a Page</a><br clear="none">
-    <a shape="rect" class="external-link" href="http://jumpstart.doublenegative.com.au/jumpstart/examples/state/passingdatabetweenpages" >Passing Data Between Pages</a></p></div><p>The session strategy stores field changes into the session; the session is created as necessary. Session strategy is the default strategy used unless otherwise overridden.</p><p>A suitably long session attribute name is used; it incorporates the name of the page, the nested component id, and the name of the field.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Example: Session Strategy</b></div><div class="codeContent panelContent pdl">
+    <a shape="rect" class="external-link" href="http://jumpstart.doublenegative.com.au/jumpstart/examples/state/passingdatabetweenpages" >Passing Data Between Pages</a></p></div>The session strategy stores field changes into the session; the session is created as necessary. Session strategy is the default strategy used unless otherwise overridden.<p>A suitably long session attribute name is used; it incorporates the name of the page, the nested component id, and the name of the field.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Example: Session Strategy</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">  @Persist
   private int value;
 </pre>

Modified: websites/production/tapestry/content/property-expressions.html
==============================================================================
--- websites/production/tapestry/content/property-expressions.html (original)
+++ websites/production/tapestry/content/property-expressions.html Sun Jul 26 21:19:56 2015
@@ -27,16 +27,6 @@
   </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 type="text/javascript">
-  SyntaxHighlighter.defaults['toolbar'] = false;
-  SyntaxHighlighter.all();
-  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,38 +57,37 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
-<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div>
+<div id="ConfluenceContent"><p>Tapestry uses <strong>property expressions</strong> to move data between components. Property expressions are the basis of the <a shape="rect" href="component-parameters.html">component parameters</a> and <a shape="rect" href="component-templates.html">template expansions</a>.</p><div class="aui-label" style="float:right" title="Related Articles">
 
-<p>Tapestry uses <strong>property expressions</strong> to move data between components. Property expressions are the basis of the <a shape="rect" href="component-parameters.html">component parameters</a> and <a shape="rect" href="component-templates.html">template expansions</a>.</p>
 
-<p>A property expression is a string that explains to Tapestry how to navigate from a root object (the containing component) through some number of properties, to a final property that can be read or updated. In fact, that's a simplification, as the properties may actually be public fields, or even method invocations.</p>
 
-<p>As elsewhere in Tapestry, the names of fields, properties, and methods are recognized in a case-insensitive manner.</p>
 
-<p>The most basic form of a property expression is a simple property name, such as "userName".</p>
 
-<p>A series of property names may be specified, separated by periods: "user.name", which is equivalent to either <code>getUser().getName()</code> or <code>getUser().setName()</code>, depending on context (whether the expression is being read or updated).</p>
 
-<p>The "." is called the "dereference operator". A second operator is "?." or the "safe dereference operator". This works the same as "." except that it allows any of the properties to be null. When reading, a null short-circuits the expression (which returns null). When writing to a property, an intermediate null value will cause the value to be discarded without error.</p>
 
-<p>In other words, "user?.name" works, even when the <code>user</code> property may be null.</p>
 
-<p>Property expressions can also reference public methods. Methods may take parameters (or not), but must not return void. When the final term in a property expression is a method, then the property expression is read-only.</p>
+<h3>Related Articles</h3>
 
-<p>Being able to invoke methods was originally added so that it was possible to access methods such as <code>java.util.Map.size()</code> (which is not named like a property getter method). In Tapestry 5.1, property expressions were extended so that parameters could be passed into methods.</p>
+<ul class="content-by-label"><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span>        </div>
 
-<p>Parameters to methods are, themselves, property expressions. This means that you can write a property expression that reads a property and passes it as a parameter to a method, and then access a property of the object returned from the method.</p>
+        <div class="details">
+                        <a shape="rect" href="component-templates.html">Component Templates</a>
+                
+                        
+                    </div>
+    </li><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span>        </div>
 
-<h2 id="PropertyExpressions-Compilation">Compilation</h2>
-
-<p>Property expressions are compiled to Java classes at runtime; there is no runtime reflection (unlike the OGNL expression language used in prior releases of Tapestry).</p>
-
-<h2 id="PropertyExpressions-Grammar">Grammar</h2>
-
-<p>Expressed in simplified <a shape="rect" class="external-link" href="http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form" >Backus&#8211;Naur Form</a>, the grammar of property expressions is as follows:</p>
-
-<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
+        <div class="details">
+                        <a shape="rect" href="component-parameters.html">Component Parameters</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div><p>A property expression is a string that explains to Tapestry how to navigate from a root object (the containing component) through some number of properties, to a final property that can be read or updated. In fact, that's a simplification, as the properties may actually be public fields, or even method invocations.</p><p>As elsewhere in Tapestry, the names of fields, properties, and methods are recognized in a case-insensitive manner.</p><p>The most basic form of a property expression is a simple property name, such as "userName".</p><p>A series of property names may be specified, separated by periods: "user.name", which is equivalent to either <code>getUser().getName()</code> or <code>getUser().setName()</code>, depending on context (whether the expression is being read or updated).</p><p>The "." is called the "dereference operator". A second operator is "?." or the "safe dereference operator". This works the same as "." except that it allows any of the properties to be nu
 ll. When reading, a null short-circuits the expression (which returns null). When writing to a property, an intermediate null value will cause the value to be discarded without error.</p><p>In other words, "user?.name" works, even when the <code>user</code> property may be null.</p><p>Property expressions can also reference public methods. Methods may take parameters (or not), but must not return void. When the final term in a property expression is a method, then the property expression is read-only.</p><p>Being able to invoke methods was originally added so that it was possible to access methods such as <code>java.util.Map.size()</code> (which is not named like a property getter method). In Tapestry 5.1, property expressions were extended so that parameters could be passed into methods.</p><p>Parameters to methods are, themselves, property expressions. This means that you can write a property expression that reads a property and passes it as a parameter to a method, and then acces
 s a property of the object returned from the method.</p><h2 id="PropertyExpressions-Compilation">Compilation</h2><p>Property expressions are compiled to Java classes at runtime; there is no runtime reflection (unlike the OGNL expression language used in prior releases of Tapestry).</p><h2 id="PropertyExpressions-Grammar">Grammar</h2><p>Expressed in simplified <a shape="rect" class="external-link" href="http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form" >Backus&#8211;Naur Form</a>, the grammar of property expressions is as follows:</p><div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent panelContent">
 <pre>expression : keyword | rangeOp | constant | propertyChain | list | notOp | map;
 
 keyword : 'null' | 'this';
@@ -131,25 +120,13 @@ mapKey : keyword | constant | propertyCh
 
 
 </pre>
-</div></div>
-
-
+</div></div><p>
 
-<div class="confluence-information-macro confluence-information-macro-information"><p class="title">Added in 5.3</p><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
+</p><div class="confluence-information-macro confluence-information-macro-information"><p class="title">Added in 5.3</p><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
 </div></div>
 <div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;">
-
 <p>Support for map literals was added in Tapestry 5.3.</p>
-</div>
-
-<p>Notes:</p>
-
-<ul><li>Whitespace is ignored.</li><li>Integers and decimals may have a leading sign ('+' or '-').</li><li>Constants are in base 10 (octal and hex notation is not yet supported). Decimals may contain a decimal point (exponent notation not yet supported).</li><li>Literal strings are enclosed in single quotes.</li><li>The <code>rangeOp</code> creates a range object that will iterate between the two values. The upper and lower bounds may be literal integers, or property expressions.</li><li>An identifier by itself is a property name. An identifier with parenthesis is a method invocation.</li><li>Property names, method names, and keywords are case-insensitive.</li><li>'this' is the root object (i.e., the containing component).</li><li>The <code>not</code> operator coerces the expression to a <code>boolean</code> (so it can be used on strings, numbers, etc.).</li><li>Method matching is based on method name and number of parameters, but not parameter types. The <a shape="rect" href="type-
 coercion.html">TypeCoercer</a> service is used to convert parameters to the correct type to be passed into the method.</li></ul>
-
-
-<h2 id="PropertyExpressions-Examples">Examples</h2>
-
-<div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>&#160;</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Example </p></th><th colspan="1" rowspan="1" class="confluenceTh"><p> Notes </p></th></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Keyword </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> this </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Keyword </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> null </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Property Name </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> userName </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Calls getUserName() or setUserName, depending on context </p></td></tr><tr><th colspan="1" 
 rowspan="1" class="confluenceTh"><p> Property Chain </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> user.address.city </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Calls getUser().getAddress().getCity() or getUser().getAddress().setCity(), depending on context </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Property Chain </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> user?.name </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Calls getUser() and, if the result is not null, calls getName() on the result </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Method Invocation </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> groupList.size() </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> calls getGroupList().size() </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Method Invocation </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p
 > members.findById(user.id)?.name </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Calls getMembers().findById(getUser().getId())?.getName() (unless findById returns null) </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Range </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> 1..10 </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Iterates between integers 1 and 10 </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Range </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> 1..groupList.size() </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Iterates between 1 and the result of getGroupList().size() </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Literal String </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> 'Beer is proof that God loves us and wants us to be happy.' </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> Use single quotes </
 p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> List </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> [user.name, user.email, user.phone] </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Not Operator </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> ! user.deleted </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> the boolean negation of getUser().getDeleted() </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Not, Coerced </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> ! user.middleName </p></td><td colspan="1" rowspan="1" class="confluenceTd"><p> true only if getUser.getMiddleName() returns null or an empty string </p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p> Map </p></th><td colspan="1" rowspan="1" class="confluenceTd"><p> { 'framework' : 'Tapestry', 'version' : version } </p></
 td><td colspan="1" rowspan="1" class="confluenceTd"><p> Keys are string literals (in single quotes), but could be properties as well </p></td></tr></tbody></table></div></div>
+</div>Notes:<ul><li>Whitespace is ignored.</li><li>Integers and decimals may have a leading sign ('+' or '-').</li><li>Constants are in base 10 (octal and hex notation is not yet supported). Decimals may contain a decimal point (exponent notation not yet supported).</li><li>Literal strings are enclosed in single quotes.</li><li>The <code>rangeOp</code> creates a range object that will iterate between the two values. The upper and lower bounds may be literal integers, or property expressions.</li><li>An identifier by itself is a property name. An identifier with parenthesis is a method invocation.</li><li>Property names, method names, and keywords are case-insensitive.</li><li>'this' is the root object (i.e., the containing component).</li><li>The <code>not</code> operator coerces the expression to a <code>boolean</code> (so it can be used on strings, numbers, etc.).</li><li>Method matching is based on method name and number of parameters, but not parameter types. The <a shape="rect"
  href="type-coercion.html">TypeCoercer</a> service is used to convert parameters to the correct type to be passed into the method.</li></ul><h2 id="PropertyExpressions-Examples">Examples</h2><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>&#160;</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Example</p></th><th colspan="1" rowspan="1" class="confluenceTh"><p>Notes</p></th></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Keyword</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>this</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Keyword</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>null</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Property Name</p></th><td colspan="1" rowspan="1" class="con
 fluenceTd"><p>userName</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Calls getUserName() or setUserName, depending on context</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Property Chain</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>user.address.city</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Calls getUser().getAddress().getCity() or getUser().getAddress().setCity(), depending on context</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Property Chain</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>user?.name</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Calls getUser() and, if the result is not null, calls getName() on the result</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Method Invocation</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>groupList.size()</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>calls getGroupList().
 size()</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Method Invocation</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>members.findById(user.id)?.name</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Calls getMembers().findById(getUser().getId())?.getName() (unless findById returns null)</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Range</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>1..10</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Iterates between integers 1 and 10</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Range</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>1..groupList.size()</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Iterates between 1 and the result of getGroupList().size()</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Literal String</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>'Beer is
  proof that God loves us and wants us to be happy.'</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Use single quotes</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>List</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>[user.name, user.email, user.phone]</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>&#160;</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Not Operator</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>! user.deleted</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>the boolean negation of getUser().getDeleted()</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Not, Coerced</p></th><td colspan="1" rowspan="1" class="confluenceTd"><p>! user.middleName</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>true only if getUser.getMiddleName() returns null or an empty string</p></td></tr><tr><th colspan="1" rowspan="1" class="confluenceTh"><p>Map</p><
 /th><td colspan="1" rowspan="1" class="confluenceTd"><p>{ 'framework' : 'Tapestry', 'version' : version }</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Keys are string literals (in single quotes), but could be properties as well</p></td></tr></tbody></table></div></div>
 </div>
 
 <div class="clearer"></div>

Modified: websites/production/tapestry/content/response-compression.html
==============================================================================
--- websites/production/tapestry/content/response-compression.html (original)
+++ websites/production/tapestry/content/response-compression.html Sun Jul 26 21:19:56 2015
@@ -27,16 +27,6 @@
   </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 type="text/javascript">
-  SyntaxHighlighter.defaults['toolbar'] = false;
-  SyntaxHighlighter.all();
-  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,30 +57,46 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><h1 id="ResponseCompression-ResponseCompression">Response Compression</h1>
+<div id="ConfluenceContent"><p>Starting in Tapestry 5.1, the framework automatically GZIP <strong>compresses</strong> content streamed to the client. This can significantly reduce the amount of network traffic for a Tapestry application, at the cost of extra processing time on the server to compress the response stream.</p><div class="aui-label" style="float:right" title="Related Articles">
 
-<div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
-<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div>
 
-<p>Starting in Tapestry 5.1, the framework automatically GZIP compresses content streamed to the client. This can significantly reduce the amount of network traffic for a Tapestry application, at the cost of extra processing time on the server to compress the response stream.</p>
 
-<p>This directly applies to both rendered pages and streamed assets from the classpath.</p>
 
-<p>Context assets will also be compressed ... but this requires referencing such assets using the "context:" binding prefix, so that generated URL is handled by Tapestry and not the servlet container.</p>
 
-<h1 id="ResponseCompression-CompressionConfiguration">Compression Configuration</h1>
 
-<p>Main Article: <a shape="rect" href="configuration.html">Configuration</a></p>
 
-<p>Small streams generally do not benefit from being compressed; there is overhead when using compression, not just the CPU time to compress the bytes, but a lot of overhead. For small responses, Tapestry does not attempt to compress the output stream.</p>
 
-<p>The configuration symbol <code>tapestry.min-gzip-size</code> allows the cutoff to be set; it defaults to 100 bytes.</p>
+<h3>Related Articles</h3>
 
-<p>In addition, some file types are already compressed and should not be recompressed (they actually get larger, not smaller!). The service <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ResponseCompressionAnalyzer.html">ResponseCompressionAnalyzer</a>'s configuration is an unordered collection of content type strings that should <em>not</em> be compressed. The default content types are "image/jpeg".</p>
+<ul class="content-by-label"><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span>        </div>
 
-<h1 id="ResponseCompression-StreamResponse">StreamResponse</h1>
+        <div class="details">
+                        <a shape="rect" href="request-processing.html">Request Processing</a>
+                
+                        
+                    </div>
+    </li><li>
+        <div>
+                <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span>        </div>
 
-<p>When returning a <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/StreamResponse.html">StreamResponse</a> from a <a shape="rect" href="page-navigation.html">component event method</a>, the stream is totally under your control; it will not be compressed. You should use the ResponseCompressionAnalyzer service to determine if the client supports compression, and add a java.util.zip.GZIPOutputStream to your stream stack if compression is desired.</p></div>
+        <div class="details">
+                        <a shape="rect" href="configuration.html">Configuration</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 shape="rect" href="assets.html">Assets</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div><p>This directly applies to both rendered pages and streamed assets from the classpath.</p><p>Context assets will also be compressed ... but this requires referencing such assets using the "context:" binding prefix, so that generated URL is handled by Tapestry and not the servlet container.</p><h1 id="ResponseCompression-CompressionConfiguration">Compression Configuration</h1><p>Main Article: <a shape="rect" href="configuration.html">Configuration</a></p><p>Small streams generally do not benefit from being compressed; there is overhead when using compression, not just the CPU time to compress the bytes, but a lot of overhead. For small responses, Tapestry does not attempt to compress the output stream.</p><p>The configuration symbol <code>tapestry.min-gzip-size</code> allows the cutoff to be set; it defaults to 100 bytes.</p><p>In addition, some file types are already compressed and should not be recompressed (they actually get larger, not smaller!). The service <a shape="rect
 " class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ResponseCompressionAnalyzer.html">ResponseCompressionAnalyzer</a>'s configuration is an unordered collection of content type strings that should <em>not</em> be compressed. The default content types are "image/jpeg".</p><h1 id="ResponseCompression-StreamResponse">StreamResponse</h1><p>When returning a <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/StreamResponse.html">StreamResponse</a> from a <a shape="rect" href="page-navigation.html">component event method</a>, the stream is totally under your control; it will not be compressed. You should use the ResponseCompressionAnalyzer service to determine if the client supports compression, and add a java.util.zip.GZIPOutputStream to your stream stack if compression is desired.</p></div>
 </div>
 
 <div class="clearer"></div>

Modified: websites/production/tapestry/content/security.html
==============================================================================
--- websites/production/tapestry/content/security.html (original)
+++ websites/production/tapestry/content/security.html Sun Jul 26 21:19:56 2015
@@ -67,8 +67,55 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><p>Tapestry has a number of security features designed to harden your application against unwanted intrusion and denial of service.</p><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
-<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div><h2 id="Security-HTTPS-onlyPages">HTTPS-only Pages</h2><p>Main Article: <a shape="rect" href="https.html">HTTPS</a></p><p>Tapestry provides several annotations and configuration settings that you can use to&#160;<span style="text-align: justify;line-height: 1.4285715;">ensure that all access to certain pages (or all pages) occurs only via the encrypted HTTPS protocol</span><span style="text-align: justify;line-height: 1.4285715;">. See&#160;<a shape="rect" href="https.html">HTTPS</a> for details.</span></p><h2 id="Security-ControllingPageAccess"><span style="text-align: justify;line-height: 1.4285715;">Controlling Page Access</span></h2><p></p><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:0 1em">
+<div id="ConfluenceContent"><p>Tapestry has a number of <strong>security</strong> features designed to harden your application against unwanted intrusion and denial of service.</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 shape="rect" href="security.html">Security</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 shape="rect" href="integrating-with-spring-framework.html">Integrating with Spring Framework</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 shape="rect" href="security-faq.html">Security FAQ</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 shape="rect" href="https.html">HTTPS</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div><p>&#160;</p><h2 id="Security-HTTPS-onlyPages">HTTPS-only Pages</h2><p>Main Article: <a shape="rect" href="https.html">HTTPS</a></p><p>Tapestry provides several annotations and configuration settings that you can use to&#160;<span style="text-align: justify;line-height: 1.4285715;">ensure that all access to certain pages (or all pages) occurs only via the encrypted HTTPS protocol</span><span style="text-align: justify;line-height: 1.4285715;">. See&#160;<a shape="rect" href="https.html">HTTPS</a> for details.</span></p><h2 id="Security-ControllingPageAccess"><span style="text-align: justify;line-height: 1.4285715;">Controlling Page Access</span></h2><p></p><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:0 1em">
 <p>    <strong>JumpStart Demo:</strong><br clear="none">
     <a shape="rect" class="external-link" href="http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/protectingpages" >Protecting Pages</a></p></div><span style="text-align: justify;line-height: 1.4285715;">For simple access control needs, you can contribute a&#160;<span><a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ComponentRequestFilter.html">ComponentRequestFilter</a> with your custom logic that decides which pages should be accessed by which users.</span></span><p><span style="line-height: 1.4285715;text-align: justify;">For more advanced needs see the Security Framework Integration section below.</span></p><h2 id="Security-White-listedPages">White-listed Pages</h2><p>Pages whose component classes are annotated with&#160;@<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/WhitelistAccessOnly.html">WhitelistAccessOnly</a>&
 #160;will only be displayed to users (clients) that are on the&#160;<em>whitelist</em>. By default the whitelist consists only of clients whose fully-qualified domain name is "localhost" (or the IP address equivalent, 127.0.0.1 or 0:0:0:0:0:0:0:1),&#160;but you can customize this by contributing to the ClientWhitelist service&#160;in your application's module class (usually AppModule.java):</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>AppModule.java (partial) &#8211; simple inline example</b></div><div class="codeContent panelContent pdl">
 <pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">    @Contribute(ClientWhitelist.class)

Modified: websites/production/tapestry/content/session-storage.html
==============================================================================
--- websites/production/tapestry/content/session-storage.html (original)
+++ websites/production/tapestry/content/session-storage.html Sun Jul 26 21:19:56 2015
@@ -67,16 +67,55 @@
   </div>
 
 <div id="content">
-<div id="ConfluenceContent"><p>&#160;</p><p>Most web applications will need to have some data that is shared across multiple pages. Perhaps you are creating a multi-page wizard, or you have an object that tracks the user's identify once logged in, or maybe you need to manage a shopping cart.</p><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
-<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div><p>Ordinary <a shape="rect" href="persistent-page-data.html">page-persistent fields</a> won't work for this, since persistent fields are available only to a specific page, not shared across multiple pages.</p><p>Tapestry provides two mechanisms for storing such data: Session State Objects and Session Attributes. When deciding between the two, it's best to use Session State Objects for complex objects, and Session Attributes for simple types.</p><h2 id="SessionStorage-SessionStateObjects">Session State Objects</h2><p>With a Session State Object (SSO), the value is automatically stored outside the page; with the default storage strategy, it is stored in the session. Such a value is global to all pages <em>for the same user</em>, but is stored separately for different users.</p><p>A field holdin
 g an SSO is marked with the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SessionState.html">SessionState</a> annotation.</p><div class="navmenu" style="float:right; background:white; margin:3px; padding:3px">
+<div id="ConfluenceContent"><p>&#160;</p><p>Most web applications will need to have some data that is shared across multiple pages. Perhaps you are creating a multi-page wizard, or you have an object that tracks the user's identify once logged in, or maybe you need to manage a shopping cart.</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 shape="rect" href="performance-and-clustering.html">Performance and Clustering</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 shape="rect" href="session-storage.html">Session Storage</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 shape="rect" href="persistent-page-data.html">Persistent Page Data</a>
+                
+                        
+                    </div>
+    </li></ul>
+</div><p>Ordinary <a shape="rect" href="persistent-page-data.html">page-persistent fields</a> won't work for this, since persistent fields are available only to a specific page, not shared across multiple pages.</p><p>Tapestry provides two mechanisms for storing such data: Session State Objects and Session Attributes. When deciding between the two, it's best to use Session State Objects for complex objects, and Session Attributes for simple types.</p><h2 id="SessionStorage-SessionStateObjects">Session State Objects</h2><p>With a Session State Object (SSO), the value is automatically stored outside the page; with the default storage strategy, it is stored in the session. Such a value is global to all pages <em>for the same user</em>, but is stored separately for different users.</p><p>A field holding an SSO is marked with the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SessionState.html">SessionState</a> ann
 otation.</p><div class="navmenu" style="float:right; background:white; margin:3px; padding:3px">
 <div class="panel" style="border-width: 1px;"><div class="panelHeader" style="border-bottom-width: 1px;"><b>Contents</b></div><div class="panelContent">
 <style type="text/css">/*<![CDATA[*/
-div.rbtoc1437340854245 {padding: 0px;}
-div.rbtoc1437340854245 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1437340854245 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1437945582068 {padding: 0px;}
+div.rbtoc1437945582068 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1437945582068 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style><div class="toc-macro rbtoc1437340854245">
-<ul class="toc-indentation"><li><a shape="rect" href="#SessionStorage-SessionStateObjects">Session State Objects</a>
+/*]]>*/</style><div class="toc-macro rbtoc1437945582068">
+<ul class="toc-indentation"><li>Related Articles</li></ul>
+<ul><li><a shape="rect" href="#SessionStorage-SessionStateObjects">Session State Objects</a>
 <ul class="toc-indentation"><li><a shape="rect" href="#SessionStorage-Pitfalls">Pitfalls</a></li><li><a shape="rect" href="#SessionStorage-CheckforCreation">Check for Creation</a></li><li><a shape="rect" href="#SessionStorage-PersistenceStrategies">Persistence Strategies</a></li><li><a shape="rect" href="#SessionStorage-ConfiguringSSOs">Configuring SSOs</a></li></ul>
 </li><li><a shape="rect" href="#SessionStorage-SessionAttributes">Session Attributes</a>
 <ul class="toc-indentation"><li><a shape="rect" href="#SessionStorage-Pitfalls.1">Pitfalls</a></li></ul>
@@ -84,7 +123,7 @@ div.rbtoc1437340854245 li {margin-left:
 <ul class="toc-indentation"><li><a shape="rect" href="#SessionStorage-@ImmutableSessionPersistedObjectAnnotation">@ImmutableSessionPersistedObject Annotation</a></li><li><a shape="rect" href="#SessionStorage-OptimizedSessionPersistedObjectInterface">OptimizedSessionPersistedObject Interface</a></li><li><a shape="rect" href="#SessionStorage-SessionPersistedObjectAnalyzerService">SessionPersistedObjectAnalyzer Service</a></li></ul>
 </li><li><a shape="rect" href="#SessionStorage-SessionLocking">Session Locking</a></li></ul>
 </div>
-</div></div></div><p>Example:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div></div>Example:<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 MyPage
 {
   @SessionState