Author: buildbot
Date: Wed Nov 11 14:19:38 2015
New Revision: 972100
Log:
Production update by buildbot for tapestry
Modified:
websites/production/tapestry/content/cache/main.pageCache
websites/production/tapestry/content/page-navigation.html
Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/tapestry/content/page-navigation.html
==============================================================================
--- websites/production/tapestry/content/page-navigation.html (original)
+++ websites/production/tapestry/content/page-navigation.html Wed Nov 11
14:19:38 2015
@@ -144,7 +144,7 @@
</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: </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&Responses">Component Event
Requests & Responses</h2><p>Main Article: <a
href="component-events.html">Component Events</a></p><p>Component event
requests may take the form of hyperlinks (<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/EventLink.html">EventLink</a>
or <a class="external-link" href="http://
tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html">ActionLink</a>)
or form submissions (<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html">Form</a>).</p><p>The
value returned from an <a href="component-events.html">event handler
method</a> controls the response sent to the client web browser.</p><p>The URL
for a component event request identifies the name of the page, the nested id of
the component, and the name of the event to trigger on the component (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 rare
ly 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;"><di
v class="codeContent panelContent pdl">
+</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: </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&Responses">Component Event
Requests & Responses</h2><p>Main Article: <a
href="component-events.html">Component Events</a></p><p>Component event
requests may take the form of hyperlinks (<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/EventLink.html">EventLink</a>
or <a class="external-link" href="http://
tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html">ActionLink</a>)
or form submissions (<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html">Form</a>).</p><p>The
value returned from an <a href="component-events.html">event handler
method</a> controls the response sent to the client web browser.</p><p>The URL
for a component event request identifies the name of the page, the nested id of
the component, and the name of the event to trigger on the component (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 rare
ly have the chance to do so (see below).</p><h3
id="PageNavigation-1.Nullresponse">1. Null response</h3><p>If the event handler
method returns no value, or returns null, then the current page (the page
containing the component) will render the response.</p><p>A page render URL for
the current page is created and sent to the client as a client side redirect.
The client browser will automatically submit a new request to generate the
page.</p><p>The user will see the newly generated content in their browser. In
addition, the URL in the browser's address bar will be a render request URL.
Render request URLs are shorter and contain less application structure (for
instance, they don't include component ids or event types). Render requests
URLs are what your users will bookmark. The component event request URLs are
transitory, meaningful only while the application is actively engaged, and not
meant to be used in later sessions.</p><div class="code panel pdl"
style="border-width: 1px;"><div
class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public Object onAction(){
return null;
}</pre>
@@ -167,30 +167,48 @@ public Object onAction(){
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public Object onAction(){
return new HttpError(302, "The Error message);
}</pre>
-</div></div><h3 id="PageNavigation-6.Linkresponse">6. Link response</h3><p>An
event handler method may return a <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Link.html">Link</a>
instance directly. The Link is converted into a URL and a client redirect to
that URL is sent to the client.</p><p>The <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html">ComponentResources</a>
object that is injected into your pages (and components) has methods for
creating component links.</p><p>The <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/PageRenderLinkSource.html">PageRenderLinkSource</a>
service can be injected to allow links to other pages to be created (though
that is rarely necessary, given the other options listed above).</p><h3
id="PageNavigation-7.Streamresponse">7. Stream response</h3><p>An event handler
can als
o return a <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/StreamResponse.html">StreamResponse</a>
object, which encapsulates a stream to be sent directly to the client browser.
This is useful for components that want to, say, generate an image or PDF and
provide it to the client.</p><h3 id="PageNavigation-8.URLresponse">8. URL
response</h3><p>A java.net.URL response is handled as a client redirect to an
external URL. (In Tapestry 5.3.x and earlier this only works for non-Ajax
requests.)</p><h3 id="PageNavigation-9.Objectresponse">9. Object
response</h3><p>Any other type of object returned from an event handler method
is an error.</p><h2 id="PageNavigation-PageRenderRequests">Page Render
Requests</h2><p>Render requests are simpler in structure and behavior than
component event requests. In the simplest case, the URL is simply the logical
name of the page.</p><p>Pages may have an <em>activation context</em>. The
activation context repre
sents persistent information about the state of the page. In practical terms,
the activation context is usually the id of some database-persistent
object.</p><p>When a page has an activation context, the values of the context
are appended to the URL path.</p><p>Not all pages have an activation
context.</p><p>The activation context may be explicitly set when the render
request link is created (the PageLink component has a context parameter for
this purpose). When no explicit activation context is provided, the page itself
is queried for its activation context.</p><p>This querying takes the form of an
event trigger. The event name is "passivate" (as we'll see shortly, there's a
corresponding "activate"). The return value of the method is used as the
context. For example:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
+</div></div><h3 id="PageNavigation-6.Linkresponse">6. Link response</h3><p>An
event handler method may return a <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Link.html">Link</a>
instance directly. The Link is converted into a URL and a client redirect to
that URL is sent to the client.</p><p>The <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html">ComponentResources</a>
object that is injected into your pages (and components) has methods for
creating component links.</p><p>The <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/PageRenderLinkSource.html">PageRenderLinkSource</a>
service can be injected to allow links to other pages to be created (though
that is rarely necessary, given the other options listed above).</p><h3
id="PageNavigation-7.Streamresponse">7. Stream response</h3><p>An event handler
can als
o return a <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/StreamResponse.html">StreamResponse</a>
object, which encapsulates a stream to be sent directly to the client browser.
This is useful for components that want to, say, generate an image or PDF and
provide it to the client.</p><h3 id="PageNavigation-8.URLresponse">8. URL
response</h3><p>A java.net.URL response is handled as a client redirect to an
external URL. (In Tapestry 5.3.x and earlier this only works for non-Ajax
requests.)</p><h3 id="PageNavigation-9.Objectresponse">9. Object
response</h3><p>Any other type of object returned from an event handler method
is an error.</p><h2 id="PageNavigation-PageRenderRequests">Page Render
Requests</h2><p>Render requests are simpler in structure and behavior than
component event requests. In the simplest case, the URL is simply the logical
name of the page.</p><p>Pages may have an <em>activation context</em>. The
activation context repre
sents persistent information about the state of the page. In practical terms,
the activation context is usually the id of some database-persistent
object.</p><p>When a page has an activation context, the values of the context
are appended to the URL path. For example,
in <code>http://www.example.com/myapp/foo/bar</code> the "myapp" part is
the servlet context (usually the name of your app), and the "foo/bar" part is
the activation context, with "foo" being the first activation parameter and
"bar" being the second.</p><p>It is common for most pages to not have any
activation context.</p><p>The activation context may be explicitly set when the
render request link is created (the PageLink component has a context parameter
for this purpose).</p><p>When no explicit activation context is provided, the
page itself is queried for its activation context. This querying takes the form
of an event trigger. The event name is "passivate" (as we'll see shortly,
there's a corresponding "activa
te"). The return value of the method is used as the context. For
example:</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 ProductDetail
{
private Product product;
-
. . .
-
long onPassivate() { return product.getId(); }
}
</pre>
-</div></div><p>The activation context may consist of a series of values, in
which case the return value of the method should be an array or a List.</p><div
class="confluence-information-macro
confluence-information-macro-information"><span class="aui-icon aui-icon-small
aui-iconfont-info confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Note: If you are using the <a
href="hibernate-user-guide.html">tapestry-hibernate</a> integration library and
your passivate context is a Hibernate entity, then you can just use the entity
itself, not its id. Tapestry will automatically extract the entity's id into
the URL, and convert it back for the "activate" event handler
method.</p></div></div><h2 id="PageNavigation-Pageactivation">Page
activation</h2><p>When a page render request arrives, the page is activated
before it is rendered.</p><div class="navmenu" style="float:right;
background:#eee; margin:3px; padding:0 1em">
+</div></div><p>The activation context may consist of a series of values, in
which case the return value of the method should be an array or a List.</p><div
class="confluence-information-macro
confluence-information-macro-information"><span class="aui-icon aui-icon-small
aui-iconfont-info confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Note: If you are using the <a
href="hibernate-user-guide.html">tapestry-hibernate</a> integration library and
your passivate context is a Hibernate entity, then you can just use the entity
itself, not its id. Tapestry will automatically extract the entity's id into
the URL, and convert it back for the "activate" event handler
method.</p></div></div><h2 id="PageNavigation-Pageactivation">Page
activation</h2><p>When a page render request arrives, the page is
<em>activated</em> before it is rendered.</p><div class="navmenu"
style="float:right; background:#eee; margin:3px; padding:0 1em">
<p> <strong>JumpStart Demos:</strong><br clear="none">
<a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/navigation/onactivateandonpassivate/3"
rel="nofollow">onActivate and onPassivate</a><br clear="none">
- <a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/handlingabadcontext/1"
rel="nofollow">Handling A Bad Context</a></p></div>Activation serves two
purposes:<ul><li>It allows the page to restore its internal state from data
encoded into the URL (the activation context discussed above).</li><li>It
provides coarse approach to validating access to the page.<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;"> . . .
-
+ <a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/handlingabadcontext/1"
rel="nofollow">Handling A Bad Context</a></p></div>Activation serves two
purposes:<ul><li>It allows the page to restore its internal state from data
encoded into the URL (the activation context discussed above).</li><li>It
provides coarse approach to validating access to the page.</li></ul><p>The
later case – 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 for verifying that
access.</p><p>Page activation uses Tapestry's <em>Component Event</em>
mechanism. See <a href="component-events.html">Component Events</a> for
details.</p><p>A page's activate event handler mirrors its passivate
handler:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> private Product product;
+ . . .
void onActivate(long productId)
{
product = productDAO.getById(productId);
}
+ . . .
+</pre>
+</div></div><p>Here's the relevant part: when the page renders, it is likely
to include more component event request URLs (links and forms). The component
event requests for those links and forms will <em>also</em> start by activating
the page, before performing other work. This forms an unbroken chain of
requests that include the same activation context.</p><p>To some degree, this
same effect could be accomplished using a <a
href="persistent-page-data.html">persistent page value</a>, but that requires
an active servlet session, and the result is not bookmarkable.</p><p>Your
activate event handler, like any event handler, may also return a value, which
is treated identically to a return value of a component event method. This
technique is commonly used as a simple access validation mechanism.</p><p>You
sometimes need to handle multiple page activation scenarios in one page class.
You could create multiple activate event handler methods with different
arguments (see the "Multiple Me
thod Matches" section at <a href="component-events.html">Component Events</a>
for details), but if you do so, you should generally
return <code>true</code> from each to avoid having more than one
activation event handler method from being called for each page request.
However, a better approach is to create one method with an EventContext
argument. Tapestry will populate the EventContext argument with all of the
activation parameters, and the EventContext's <code>get</code> method will
retrieve and coerce each parameter to the desired type. For example:</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(EventContext eventContext) {
+
+ String color = DEFAULT_COLOR;
+
+ if (eventContext.getCount() > 0) {
+ long productId = eventContext.get(Long.class, 0);
+
+ if (eventContext.getCount() > 1) {
+ String color = eventContext.get(String.class, 1);
+ }
+ product = productDAO.getById(productId, color);
+ } else {
+ return SelectProduct.class; // no product selected
+ }
+ }
. . .
</pre>
-</div></div><p>Here's the relevant part: when the page renders, it is likely
to include more component event request URLs (links and forms). The component
event requests for those links and forms will <em>also</em> start by activating
the page, before performing other work. This forms an unbroken chain of
requests that include the same activation context.</p><p>To some degree, this
same effect could be accomplished using a <a
href="persistent-page-data.html">persistent page value</a>, but that requires
an active session, and the result is not bookmarkable.</p><p>The activate event
handler may also return a value, which is treated identically to a return value
of a component event request event trigger. This will typically be used in an
access validation scenario.</p><h2
id="PageNavigation-PageNavigationPatterns">Page Navigation Patterns</h2><p>This
combination of action links and context and page context can be put together in
any number of ways.</p><p>Let's take a typical master/d
etail relationship using the concept of a product catalog page. In this
example, the ProductListing page is a list of products, and the ProductDetails
page must display the details for a specific product.</p><h3
id="PageNavigation-Pattern1:Componenteventrequests/PersistentData">Pattern 1:
Component event requests / Persistent Data</h3><p>In this pattern, the
ProductListing page uses action events and a persistent field on the
ProductDetails page.</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>ProductListing.html</b></div><div class="codeContent panelContent pdl">
+</div></div><h2 id="PageNavigation-PageNavigationPatterns">Page Navigation
Patterns</h2><p>This combination of action links and context and page context
can be put together in any number of ways.</p><p>Let's take a typical
master/detail relationship using the concept of a product catalog page. In this
example, the ProductListing page is a list of products, and the ProductDetails
page must display the details for a specific product.</p><h3
id="PageNavigation-Pattern1:Componenteventrequests/PersistentData">Pattern 1:
Component event requests / Persistent Data</h3><p>In this pattern, the
ProductListing page uses action events and a persistent field on the
ProductDetails page.</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>ProductListing.html</b></div><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> <t:loop source="products" value="product">
<a t:type="actionlink" t:id="select"
context="product.id">${product.name}</a>
</t:loop>