Author: buildbot
Date: Mon Feb 19 19:21:08 2018
New Revision: 1025617
Log:
Production update by buildbot for tapestry
Modified:
websites/production/tapestry/content/ajax-components-faq.html
websites/production/tapestry/content/beaneditform-faq.html
websites/production/tapestry/content/cache/main.pageCache
websites/production/tapestry/content/component-events-faq.html
websites/production/tapestry/content/configuration.html
websites/production/tapestry/content/forms-and-form-components-faq.html
websites/production/tapestry/content/hibernate-support-faq.html
websites/production/tapestry/content/how-to-upgrade.html
websites/production/tapestry/content/injection-faq.html
websites/production/tapestry/content/integration-with-existing-applications.html
websites/production/tapestry/content/javascript-faq.html
websites/production/tapestry/content/limitations.html
websites/production/tapestry/content/link-components-faq.html
websites/production/tapestry/content/maven-support-faq.html
websites/production/tapestry/content/release-notes-50.html
websites/production/tapestry/content/release-notes-51.html
websites/production/tapestry/content/release-notes-52.html
websites/production/tapestry/content/release-notes-53.html
websites/production/tapestry/content/release-notes-531.html
websites/production/tapestry/content/release-notes-532.html
websites/production/tapestry/content/release-notes-533.html
websites/production/tapestry/content/release-notes-534.html
websites/production/tapestry/content/release-notes-535.html
websites/production/tapestry/content/release-notes-536.html
websites/production/tapestry/content/release-upgrade-faq.html
websites/production/tapestry/content/request-processing-faq.html
websites/production/tapestry/content/security-faq.html
websites/production/tapestry/content/specific-errors-faq.html
websites/production/tapestry/content/tapestry-inversion-of-control-faq.html
Modified: websites/production/tapestry/content/ajax-components-faq.html
==============================================================================
--- websites/production/tapestry/content/ajax-components-faq.html (original)
+++ websites/production/tapestry/content/ajax-components-faq.html Mon Feb 19
19:21:08 2018
@@ -77,7 +77,14 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="AjaxComponentsFAQ-AjaxComponents">Ajax Components</h2><p>Main article: <a
href="ajax-components-faq.html">Ajax Components FAQ</a></p><h3
id="AjaxComponentsFAQ-DoIhavetospecifybothidandt:idforZonecomponents?">Do I
have to specify both <code>id</code> and <code>t:id</code> for Zone
components?</h3><p>The examples for the Zone component (in the Component
Reference) consistently specify both <code>id</code> and <code>t:id</code> and
this is probably a good idea.</p><p>Generally speaking, if you don't specify
the client-side id (the <code>id</code> attribute), it will be the same as the
Tapestry component id (<code>t:id</code>).</p><p>However, there are any number
of exceptions to this rule. The Zone may be rendering inside a Loop (in which
case, each rendering will have a unique client side id). The Zone may be
rendering as part of a partial page render, in which case, a random unique id
is inserted into the id. There are other exampl
es where Tapestry component ids in nested components may also clash.</p><p>The
point is, to be sure, specify the exact client id. This will be the value for
the <code>zone</code> parameter of the triggering component (such as a Form,
PageLink, ActionLink, etc.).</p><h3
id="AjaxComponentsFAQ-HowdoIupdatethecontentofaZonefromaneventhandlermethod?">How
do I update the content of a Zone from an event handler method?</h3><p>When a
client-side link or form triggers an update, the return value from the event
handler method is used to construct a partial page response; this partial page
response includes markup content that is used to update the Zone's client-side
<code><div></code> element.</p><p>Where does that content come from? You
inject it into your page.</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
+ <div id="ConfluenceContent"><h1
id="AjaxComponentsFAQ-AjaxComponents">Ajax Components</h1><p>Main article: <a
href="ajax-and-zones.html">Ajax and Zones</a></p><h2
id="AjaxComponentsFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
+div.rbtoc1519068036620 {padding: 0px;}
+div.rbtoc1519068036620 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068036620 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068036620">
+<ul class="toc-indentation"><li><a
href="#AjaxComponentsFAQ-DoIhavetospecifybothidandt:idforZonecomponents?">Do I
have to specify both id and t:id for Zone components?</a></li><li><a
href="#AjaxComponentsFAQ-HowdoIupdatethecontentofaZonefromaneventhandlermethod?">How
do I update the content of a Zone from an event handler method?</a></li><li><a
href="#AjaxComponentsFAQ-HowtoIupdatemultiplezonesinasingleeventhandler?">How
to I update multiple zones in a single event handler?</a></li><li><a
href="#AjaxComponentsFAQ-What'sthatweirdnumberinthemiddleoftheclientidsafteraZoneisupdated?">What's
that weird number in the middle of the client ids after a Zone is
updated?</a></li><li><a
href="#AjaxComponentsFAQ-WhydoIsometimesgettheexception"Therenderedcontentdidnotincludeanyelementsthatallowforthepositioningofthehiddenformfield'selement."whenrenderinganemptyZone?">Why
do I sometimes get the exception "The rendered content did not include any
elements that allow for the positioni
ng of the hidden form field's element." when rendering an empty
Zone?</a></li></ul>
+</div><h2
id="AjaxComponentsFAQ-DoIhavetospecifybothidandt:idforZonecomponents?">Do I
have to specify both <code>id</code> and <code>t:id</code> for Zone
components?</h2><p>The examples for the Zone component (in the Component
Reference) consistently specify both <code>id</code> and <code>t:id</code> and
this is probably a good idea.</p><p>Generally speaking, if you don't specify
the client-side id (the <code>id</code> attribute), it will be the same as the
Tapestry component id (<code>t:id</code>).</p><p>However, there are any number
of exceptions to this rule. The Zone may be rendering inside a Loop (in which
case, each rendering will have a unique client side id). The Zone may be
rendering as part of a partial page render, in which case, a random unique id
is inserted into the id. There are other examples where Tapestry component ids
in nested components may also clash.</p><p>The point is, to be sure, specify
the exact client id. This will be the value for the <code>zone</code> p
arameter of the triggering component (such as a Form, PageLink, ActionLink,
etc.).</p><h2
id="AjaxComponentsFAQ-HowdoIupdatethecontentofaZonefromaneventhandlermethod?">How
do I update the content of a Zone from an event handler method?</h2><p>When a
client-side link or form triggers an update, the return value from the event
handler method is used to construct a partial page response; this partial page
response includes markup content that is used to update the Zone's client-side
<code><div></code> element.</p><p>Where does that content come from? You
inject it into your page.</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><t:zone id="search" t:id="searchZone">
<t:form t:id="searchForm" zone="searchZone">
<t:textfield t:id="query" size="20"/>
@@ -111,7 +118,7 @@
return statusZone.getBody();
}
</pre>
-</div></div><h3
id="AjaxComponentsFAQ-HowtoIupdatemultiplezonesinasingleeventhandler?">How to I
update multiple zones in a single event handler?</h3><p>To do this, you must
know, on the server, the client ids of each Zone. That's one of the reasons
that you will generally set the Zone's client id (via the Zone's id parameter),
rather than let Tapestry assign a client id for you.</p><p>From the event
handler method, instead of returning a Block or a Component, return a
multi-zone update:</p><p> </p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>Multiple Zone Update (5.3+)</b></div><div
class="codeContent panelContent pdl">
+</div></div><h2
id="AjaxComponentsFAQ-HowtoIupdatemultiplezonesinasingleeventhandler?">How to I
update multiple zones in a single event handler?</h2><p>To do this, you must
know, on the server, the client ids of each Zone. That's one of the reasons
that you will generally set the Zone's client id (via the Zone's id parameter),
rather than let Tapestry assign a client id for you.</p><p>From the event
handler method, instead of returning a Block or a Component, return a
multi-zone update:</p><p> </p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>Multiple Zone Update (5.3+)</b></div><div
class="codeContent panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> @Inject
private Block searchResults;
@@ -130,7 +137,7 @@
ajaxResponseRenderer.addRender("results",
searchResults).addRender("status", statusBlock);
}
</pre>
-</div></div><p>Note: Users of Tapestry 5.2 and earlier (which didn't support
AjaxResponseRenderer) must replace that last line with: <code>return new
MultiZoneUpdate("results", searchResults).add("status",
statusBlock);</code></p><p>AjaxResponseRenderer adds other useful commands as
well. It also has the advantage that a simple return value can be returned to
render content for the Zone that triggered the request.</p><h3
id="AjaxComponentsFAQ-What'sthatweirdnumberinthemiddleoftheclientidsafteraZoneisupdated?">What's
that weird number in the middle of the client ids after a Zone is
updated?</h3><p>You might start with markup in your template for a component
such as a TextField:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
+</div></div><p>Note: Users of Tapestry 5.2 and earlier (which didn't support
AjaxResponseRenderer) must replace that last line with: <code>return new
MultiZoneUpdate("results", searchResults).add("status",
statusBlock);</code></p><p>AjaxResponseRenderer adds other useful commands as
well. It also has the advantage that a simple return value can be returned to
render content for the Zone that triggered the request.</p><h2
id="AjaxComponentsFAQ-What'sthatweirdnumberinthemiddleoftheclientidsafteraZoneisupdated?">What's
that weird number in the middle of the client ids after a Zone is
updated?</h2><p>You might start with markup in your template for a component
such as a TextField:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <t:textfield t:id="firstName"/>
</pre>
</div></div><p>When the component initially renders as part of a full page
render, you get a sensible bit of markup:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
@@ -139,7 +146,7 @@
</div></div><p>But when the form is inside a Zone and rendered as part of a
zone update, the ids get weird:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <input id="firstName_12a820cc40e"
name="firstName" type="text">
</pre>
-</div></div><p>What's happening here is that Tapestry is working to prevent
unwanted id clashes as part of the page update. In an HTML document, each
<code>id</code> is expected to be unique; most JavaScript is keyed off of the
<code>id</code> field, for instance.</p><p>In a full page render, components
don't just use their component id (<code>t:id</code>) as their client id;
instead they use the <code>JavaScriptSupport</code> environmental to allocate a
unique id. When there's no loops or conflicts, the client id matches the
component id.</p><p>When the component is inside a loop, a suffix is appended:
<code>firstName</code>, <code>firstName_0</code>, <code>firstName_1</code>,
etc.</p><p>When the component is rendered as part of an Ajax partial page
update, the rules are different. Since Tapestry doesn't know what content has
been rendered onto the page previously, it can't use its normal tricks to
ensure that ids are unique.</p><p>Instead, Tapestry creates a random-ish unique
id s
uffix, such as "12a820cc40e" in the example; this suffix is appended to all
allocated ids to ensure that they do not conflict with previously rendered
ids.</p><h3
id="AjaxComponentsFAQ-WhydoIsometimesgettheexception"Therenderedcontentdidnotincludeanyelementsthatallowforthepositioningofthehiddenformfield'selement."whenrenderinganemptyZone?">Why
do I sometimes get the exception "The rendered content did not include any
elements that allow for the positioning of the hidden form field's element."
when rendering an empty Zone?</h3><p>As part of Tapestry's form processing, it
must write a hidden input element with information needed when the form is
submitted. Since the content of a Zone may be changed or removed, a hidden
field is created just for the Zone, separate from the rest of the enclosing
form.</p><p>At the same time, Tapestry wants to position the <input>
field in a valid location, and HTML defines some constraints for that; an input
field must appear inside a &l
t;p> or <div> element. If your zone is initially empty, there's no
place to put the hidden element, and Tapestry will complain.</p><p>The solution
is simple: just add a <div> element to the body of the zone. This<span>
ensures that there's a place for the hidden input field.  An empty
<div> element (even one containing a hidden form field) will not affect
page layout.</span></p></div>
+</div></div><p>What's happening here is that Tapestry is working to prevent
unwanted id clashes as part of the page update. In an HTML document, each
<code>id</code> is expected to be unique; most JavaScript is keyed off of the
<code>id</code> field, for instance.</p><p>In a full page render, components
don't just use their component id (<code>t:id</code>) as their client id;
instead they use the <code>JavaScriptSupport</code> environmental to allocate a
unique id. When there's no loops or conflicts, the client id matches the
component id.</p><p>When the component is inside a loop, a suffix is appended:
<code>firstName</code>, <code>firstName_0</code>, <code>firstName_1</code>,
etc.</p><p>When the component is rendered as part of an Ajax partial page
update, the rules are different. Since Tapestry doesn't know what content has
been rendered onto the page previously, it can't use its normal tricks to
ensure that ids are unique.</p><p>Instead, Tapestry creates a random-ish unique
id s
uffix, such as "12a820cc40e" in the example; this suffix is appended to all
allocated ids to ensure that they do not conflict with previously rendered
ids.</p><h2
id="AjaxComponentsFAQ-WhydoIsometimesgettheexception"Therenderedcontentdidnotincludeanyelementsthatallowforthepositioningofthehiddenformfield'selement."whenrenderinganemptyZone?">Why
do I sometimes get the exception "The rendered content did not include any
elements that allow for the positioning of the hidden form field's element."
when rendering an empty Zone?</h2><p>As part of Tapestry's form processing, it
must write a hidden input element with information needed when the form is
submitted. Since the content of a Zone may be changed or removed, a hidden
field is created just for the Zone, separate from the rest of the enclosing
form.</p><p>At the same time, Tapestry wants to position the <input>
field in a valid location, and HTML defines some constraints for that; an input
field must appear inside a &l
t;p> or <div> element. If your zone is initially empty, there's no
place to put the hidden element, and Tapestry will complain.</p><p>The solution
is simple: just add a <div> element to the body of the zone. This<span>
ensures that there's a place for the hidden input field.  An empty
<div> element (even one containing a hidden form field) will not affect
page layout.</span></p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/beaneditform-faq.html
==============================================================================
--- websites/production/tapestry/content/beaneditform-faq.html (original)
+++ websites/production/tapestry/content/beaneditform-faq.html Mon Feb 19
19:21:08 2018
@@ -78,11 +78,11 @@
<div id="content">
<div id="ConfluenceContent"><h1
id="BeanEditFormFAQ-BeanEditForm">BeanEditForm</h1><p>Main Article: <a
href="beaneditform-guide.html">BeanEditForm Guide</a></p><h2
id="BeanEditFormFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1519064398641 {padding: 0px;}
-div.rbtoc1519064398641 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1519064398641 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1519068040277 {padding: 0px;}
+div.rbtoc1519068040277 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068040277 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1519064398641">
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068040277">
<ul class="toc-indentation"><li><a
href="#BeanEditFormFAQ-WhydoIgetexceptionsaboutinstantiatingabeanwhenusingBeanEditForm?">Why
do I get exceptions about instantiating a bean when using
BeanEditForm?</a></li><li><a
href="#BeanEditFormFAQ-What'sthedifferencebetweenBeanEditorandBeanEditForm?">What's
the difference between BeanEditor and BeanEditForm?</a></li><li><a
href="#BeanEditFormFAQ-HowdoIcustomizethelayoutoftheBeanEditForm?">How do I
customize the layout of the BeanEditForm?</a></li></ul>
</div><h2
id="BeanEditFormFAQ-WhydoIgetexceptionsaboutinstantiatingabeanwhenusingBeanEditForm?">Why
do I get exceptions about instantiating a bean when using
BeanEditForm?</h2><p>When you render a BeanEditForm, or when the rendered form
is submitted, Tapestry must instantiate an instance of the object to be edited.
This occurs when the BeanEditForm's <code>object</code> parameter is bound to
null: Tapestry instantiates an instance of the property type so that the
BeanEditForm has an object to read default values from, or to push submitted
values into.</p><p>By default, this uses the standard <a
href="injection-in-detail.html">injection mechanism</a>, which means that
Tapestry will identify the public constructor with the most parameters, and
attempt to find objects and other objects for each constructor
parameter.</p><p>There's two ways to fine tune this so you don't get
errors:</p><ul><li>Place an @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apac
he/tapestry5/ioc/annotations/Inject.html">Inject</a> annotation on the correct
constructor to use (often, the constructor with no parameters).</li></ul><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 MyBean {
Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/tapestry/content/component-events-faq.html
==============================================================================
--- websites/production/tapestry/content/component-events-faq.html (original)
+++ websites/production/tapestry/content/component-events-faq.html Mon Feb 19
19:21:08 2018
@@ -77,14 +77,20 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="ComponentEventsFAQ-ComponentEvents">Component Events</h2><h3
id="ComponentEventsFAQ-WhydoesTapestrysendaredirectafteraformissubmitted?">Why
does Tapestry send a redirect after a form is submitted?</h3><p>This is an
extension of the <a class="external-link"
href="http://en.wikipedia.org/wiki/Post/Redirect/Get"
rel="nofollow">Post/Redirect/Get</a> approach. It ensures that after an
operation that updates server-side state, such as a form submission, if the
user resubmits the resulting page, the operation is <strong>not</strong>
performed a second time; instead just the results of the operation, reflecting
the changed server-side state, is re-rendered.</p><p>This has the unwanted
requirement that any data needed to render the response must persist between
the event request (the form submission) and the render request; this often
means that fields must be annotated with @<a class="external-link"
href="http://tapestry.apache.org/curre
nt/apidocs/org/apache/tapestry5/annotations/Persist.html">Persist</a>.
+ <div id="ConfluenceContent"><h1
id="ComponentEventsFAQ-ComponentEvents">Component Events</h1><p>Main Article:
<a href="component-events.html">Component Events</a></p><h2
id="ComponentEventsFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
+div.rbtoc1519068039274 {padding: 0px;}
+div.rbtoc1519068039274 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068039274 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068039274">
+<ul class="toc-indentation"><li><a
href="#ComponentEventsFAQ-WhydoesTapestrysendaredirectafteraformissubmitted?">Why
does Tapestry send a redirect after a form is submitted?</a></li><li><a
href="#ComponentEventsFAQ-IspecifiedazoneinmyActionLink/EventLink,sowhydoesn'tmyeventfireviaajax(request.isXHR()isfalse)?">I
specified a zone in my ActionLink/EventLink, so why doesn't my event fire via
ajax (request.isXHR() is false)?</a></li></ul>
+</div><h2
id="ComponentEventsFAQ-WhydoesTapestrysendaredirectafteraformissubmitted?">Why
does Tapestry send a redirect after a form is submitted?</h2><p>This is an
extension of the <a class="external-link"
href="http://en.wikipedia.org/wiki/Post/Redirect/Get"
rel="nofollow">Post/Redirect/Get</a> approach. It ensures that after an
operation that updates server-side state, such as a form submission, if the
user resubmits the resulting page, the operation is <strong>not</strong>
performed a second time; instead just the results of the operation, reflecting
the changed server-side state, is re-rendered.</p><p>This has the unwanted
requirement that any data needed to render the response must persist between
the event request (the form submission) and the render request; this often
means that fields must be annotated with @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Persist.html">Persist</a>.
</p><div class="aui-message aui-message-info">
Added in 5.2
If you want to short-circuit this behavior and render a response directly,
your component event handle method may return an instance of
[StreamPageContent|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/StreamPageContent.html].
Tapestry will render the page as part of the event request and stream its
content back to the client web browser, rather than sending the normal redirect.
-
</div>
@@ -92,8 +98,7 @@ Added in 5.2
<div class="aui-message aui-message-info">
Added in 5.4
Starting in release 5.4, Forms (by default) will NOT redirect after post if
there are validation errors. This makes it possible to re-render the page, with
error decorations, without requiring that the validation errors be stored in
the session between requests ... and that means that the application can remain
stateless much longer.
-
-</div><h3
id="ComponentEventsFAQ-IspecifiedazoneinmyActionLink/EventLink,sowhydoesn'tmyeventfireviaajax(request.isXHR()isfalse)?">I
specified a zone in my ActionLink/EventLink, so why doesn't my event fire via
ajax (request.isXHR() is false)?</h3><p>Check your browser's JavaScript console
for errors. It's likely that a JavaScript error has prevented Tapestry from
transforming your ActionLink/EventLink from a page render action to an ajax
action.</p></div>
+</div><h2
id="ComponentEventsFAQ-IspecifiedazoneinmyActionLink/EventLink,sowhydoesn'tmyeventfireviaajax(request.isXHR()isfalse)?">I
specified a zone in my ActionLink/EventLink, so why doesn't my event fire via
ajax (request.isXHR() is false)?</h2><p>Check your browser's JavaScript console
for errors. It's likely that a JavaScript error has prevented Tapestry from
transforming your ActionLink/EventLink from a page render action to an ajax
action.</p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/configuration.html
==============================================================================
--- websites/production/tapestry/content/configuration.html (original)
+++ websites/production/tapestry/content/configuration.html Mon Feb 19 19:21:08
2018
@@ -147,12 +147,12 @@
<h1 id="Configuration-ConfiguringTapestry">Configuring Tapestry</h1><p>This
page discusses all the ways in which Tapestry can be configured. Tapestry
applications are configured almost entirely using Java, with very little XML at
all.</p><p><strong>Contents</strong></p><p><style type="text/css">/*<![CDATA[*/
-div.rbtoc1518970800044 {padding: 0px;}
-div.rbtoc1518970800044 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1518970800044 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1519068033351 {padding: 0px;}
+div.rbtoc1519068033351 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068033351 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1518970800044">
-<ul class="toc-indentation"><li><a
href="#Configuration-XMLconfiguration(web.xml)">XML configuration
(web.xml)</a></li><li><a
href="#Configuration-YourApplication'sModuleClass">Your Application's Module
Class</a></li><li><a
href="#Configuration-ConfigurationSymbolNames">Configuration Symbol
Names</a></li><li><a
href="#Configuration-SettingComponentParameterDefaults">Setting Component
Parameter Defaults</a></li><li><a
href="#Configuration-ConfiguringIgnoredPaths">Configuring Ignored
Paths</a></li><li><a
href="#Configuration-ConfiguringContentTypeMapping">Configuring Content Type
Mapping</a></li><li><a href="#Configuration-SettingExecutionModes">Setting
Execution Modes</a></li></ul>
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068033351">
+<ul class="toc-indentation"><li><a
href="#Configuration-XMLconfiguration(web.xml)">XML configuration
(web.xml)</a></li><li><a
href="#Configuration-YourApplication'sModuleClass">Your Application's Module
Class</a></li><li><a
href="#Configuration-ConfigurationSymbolNames">Configuration Symbol
Names</a></li><li><a
href="#Configuration-SettingComponentParameterDefaults">Setting Component
Parameter Defaults</a></li><li><a
href="#Configuration-ConfiguringIgnoredPaths">Configuring Ignored
Paths</a></li><li><a
href="#Configuration-ConfiguringContentTypeMapping">Configuring Content Type
Mapping</a></li><li><a href="#Configuration-SettingExecutionModes">Setting
Execution Modes</a></li><li><a
href="#Configuration-SegregatingApplicationsIntoFolders">Segregating
Applications Into Folders</a></li></ul>
</div><h2 id="Configuration-XMLconfiguration(web.xml)">XML configuration
(web.xml)</h2><p>Tapestry runs on top of the standard Java Servlet API. To the
servlet container, such as Tomcat, Tapestry appears as a <em>servlet
filter</em>. This gives Tapestry great flexibility in matching URLs without
requiring lots of XML configuration.</p><p>Although most configuration is done
with Java, a small but necessary amount of configuration occurs inside the
servlet deployment descriptor, WEB-INF/web.xml. Most of the configuration is
boilerplate, nearly the same for all applications.</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>web.xml (partial)</b></div><div
class="codeContent panelContent pdl">
<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
@@ -506,7 +506,7 @@ Added in 5.3
</div></div><p>Execution mode itself may be a comma separated list:</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;">-Dtapestry.execution-mode=uat,integration jetty:run
</pre>
-</div></div><p><span style="color: rgb(83,145,38);">Segregating Applications
Into Folders</span></p><p>In many cases where Tapestry is being adopted into an
existing web application (possibly written in Tapestry 4 or some other
framework), it is nice to segregate the Tapestry application into its own
folder, to avoid conflicts with the existing application or servlets.</p>
+</div></div><h2 id="Configuration-SegregatingApplicationsIntoFolders"><span
style="color: rgb(83,145,38);">Segregating Applications Into
Folders</span></h2><p>In many cases where Tapestry is being adopted into an
existing web application (possibly written in Tapestry 4 or some other
framework), it is nice to segregate the Tapestry application into its own
folder, to avoid conflicts with the existing application or servlets.</p>
Modified:
websites/production/tapestry/content/forms-and-form-components-faq.html
==============================================================================
--- websites/production/tapestry/content/forms-and-form-components-faq.html
(original)
+++ websites/production/tapestry/content/forms-and-form-components-faq.html Mon
Feb 19 19:21:08 2018
@@ -77,12 +77,12 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h1
id="FormsandFormComponentsFAQ-FormsandFormComponents">Forms and Form
Components</h1><p>Main article: <a href="forms-and-validation.html">Forms and
Validation</a></p><h3
id="FormsandFormComponentsFAQ-Contents">Contents</h3><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1519064398334 {padding: 0px;}
-div.rbtoc1519064398334 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1519064398334 li {margin-left: 0px;padding-left: 0px;}
+ <div id="ConfluenceContent"><h1
id="FormsandFormComponentsFAQ-FormsandFormComponents">Forms and Form
Components</h1><p>Main article: <a href="forms-and-validation.html">Forms and
Validation</a></p><h2
id="FormsandFormComponentsFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
+div.rbtoc1519068036336 {padding: 0px;}
+div.rbtoc1519068036336 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068036336 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1519064398334">
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068036336">
<ul class="toc-indentation"><li><a
href="#FormsandFormComponentsFAQ-Whatisthet:formdatahiddenfieldfor?">What is
the t:formdata hidden field for?</a></li><li><a
href="#FormsandFormComponentsFAQ-HowdoIchangethelabelforafieldonthefly?">How do
I change the label for a field on the fly?</a></li><li><a
href="#FormsandFormComponentsFAQ-Tapestryfocusesonthewrongfieldinmyform,howdoIfixthat?">Tapestry
focuses on the wrong field in my form, how do I fix that?</a></li></ul>
</div><h2
id="FormsandFormComponentsFAQ-Whatisthet:formdatahiddenfieldfor?">What is the
<code>t:formdata</code> hidden field for?</h2><p>In Tapestry, rendering a form
can be a complicated process; inside the body of the Form component are many of
field components: TextField, Select, TextArea, and so forth. Each of these must
pull data out of your data model and convert it to the string form used inside
the client web browser. In addition, JavaScript to support client-side
validation must be generated. This can be further complicated by the use of
Loop and If components, or made really complicated by the use of Block (to
render portions of other pages: this is what the BeanEditForm component
does).</p><p>Along the way, the Form is generating unique form control names
for each field component, as it renders.</p><p>When the client-side Form is
submitted, an event is triggered on the server-side Form component. It now
needs to locate each component, in turn, inform the component of its
control name, and allow the component to read the corresponding query
parameter. The component then converts the client-side string back into a
server-side value and performs validations before updating the data
model.</p><p>That's where <code>t:formdata</code> comes in. While components
are rendering, they are using the FormSupport environmental object to record
callbacks:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>FormSupport.java (partial)</b></div><div class="codeContent
panelContent pdl">
<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;">public interface FormSupport extends ClientElement
Modified: websites/production/tapestry/content/hibernate-support-faq.html
==============================================================================
--- websites/production/tapestry/content/hibernate-support-faq.html (original)
+++ websites/production/tapestry/content/hibernate-support-faq.html Mon Feb 19
19:21:08 2018
@@ -77,7 +77,14 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="HibernateSupportFAQ-HibernateSupport">Hibernate Support</h2><p>Main
article: <a href="hibernate-support-faq.html">Hibernate Support FAQ</a></p><h3
id="HibernateSupportFAQ-HowdoIgetHibernatetostartupupwhentheapplicationstartsup,ratherthanlazilywiththefirstrequestfortheapplication?">How
do I get Hibernate to startup up when the application starts up, rather than
lazily with the first request for the application?</h3><p>This was a minor
problem in 5.0; by 5.1 it is just a matter of overriding the configuration
system <code>tapestry.hibernate-early-startup</code> to "true".</p></div>
+ <div id="ConfluenceContent"><h1
id="HibernateSupportFAQ-HibernateSupport">Hibernate Support</h1><p>Main
article: <a href="hibernate.html">Hibernate</a></p><h2
id="HibernateSupportFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
+div.rbtoc1519068037169 {padding: 0px;}
+div.rbtoc1519068037169 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068037169 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068037169">
+<ul class="toc-indentation"><li><a
href="#HibernateSupportFAQ-HowdoIgetHibernatetostartupupwhentheapplicationstartsup,ratherthanlazilywiththefirstrequestfortheapplication?">How
do I get Hibernate to startup up when the application starts up, rather than
lazily with the first request for the application?</a></li></ul>
+</div><h2
id="HibernateSupportFAQ-HowdoIgetHibernatetostartupupwhentheapplicationstartsup,ratherthanlazilywiththefirstrequestfortheapplication?">How
do I get Hibernate to startup up when the application starts up, rather than
lazily with the first request for the application?</h2><p>This was a minor
problem in 5.0; by 5.1 it is just a matter of overriding the configuration
system <code>tapestry.hibernate-early-startup</code> to "true".</p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/how-to-upgrade.html
==============================================================================
--- websites/production/tapestry/content/how-to-upgrade.html (original)
+++ websites/production/tapestry/content/how-to-upgrade.html Mon Feb 19
19:21:08 2018
@@ -67,7 +67,7 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><p>Upgrading from one Tapestry
version to the next is usually quite easy. Backward compatibility is one of
Tapestry's <a href="how-to-upgrade.html">core principles</a>. Even so,
sometimes a checklist comes in handy to be sure you consider all of the
implications of an upgrade.</p><h2 id="HowtoUpgrade-BeforeYouUpgrade">Before
You Upgrade</h2><ol><li><strong>Check Java version compatibility: </strong>See
the compatibility matrix at <strong><a
href="supported-environments-and-versions.html">Supported Environments and
Versions</a></strong>.<strong><br clear="none"></strong></li><li><strong>Check
3rd Party compatibility:</strong> Find out whether your 3rd party modules are
compatible with the new version of Tapestry. Although the Tapestry developers
try very hard to maintain backward compatibility across versions, sometimes an
older version of a 3rd party module (particularly if it uses internal APIs)
won't work with a newly-released version
of Tapestry, and in that case you may have to wait until that 3rd party module
is updated by its developers.</li><li><strong>Find and replace all calls to
deprecated APIs.</strong> Those are the places most likely to be broken after
the upgrade. Most IDEs make it easy to find all deprecated items. In Eclipse,
for example, the "Problems" view will show warnings for the use of deprecated
APIs if you set it to show "All Errors/Warnings on
Project".</li><li><strong>Read the Release Notes:</strong> Each Tapestry
version has a <a href="how-to-upgrade.html">How to Upgrade</a> document that
lists all of the changes, including some that may cause compatibility issues
with your current code. You will save yourself a lot of frustration if you
carefully read this material before proceeding.</li></ol><h2
id="HowtoUpgrade-Upgrading">Upgrading</h2><ol><li><strong>Upgrade one step at a
time:</strong> It is usually best to upgrade to each intermediate version of
Tapestry rather than skipping ahead
multiple versions. Skipping versions (except for minor bug fix releases) makes
it harder to find all calls to deprecated APIs (see
above).</li><li><strong>Update your POM (or download the JARs
manually):</strong> If you're using Maven (or Gradle), update the version of
the Tapestry dependencies in your pom.xml (or build.gradle) file. Remember to
keep all of the Tapestry-supplied modules in sync. For example, don't forget to
update the version of Tapestry-hibernate, Tapestry-spring, Tapestry-upload,
etc.</li><li><strong>Remove old Tapestry JARs:</strong> If you're not using
Maven or Gradle (e.g. if you have the Tapestry JARs in your lib directory), be
sure you remove older versions of Tapestry JARs (including JARs for any
Tapestry-supplied modules).</li></ol><h2
id="HowtoUpgrade-AfterYouUpgrade">After You Upgrade</h2><ol><li><strong>Remove
cached JavaScript:</strong> Tapestry's internal JavaScript may change between
releases, and your web browser may have cached the older version. If
you have set a specific <a href="how-to-upgrade.html">application
version</a> in your application's module class (usually AppModule.java), you
should increment it to ensure that the URLs to the JavaScript files will have a
new version number in their paths. Doing so will cause the browser to download
the latest versions from your server. Alternatively, you can just clear your
browser's cache (and have all your developers and testers do the same).
<em>This issue is usually not a problem on production servers, since you will
likely increment the application version with each new production
release.</em></li></ol><p></p></div>
+ <div id="ConfluenceContent"><p>Upgrading from one Tapestry
version to the next is usually quite easy. Backward compatibility is one of
Tapestry's <a href="principles.html">core principles</a>. Even so, sometimes a
checklist comes in handy to be sure you consider all of the implications of an
upgrade.</p><h2 id="HowtoUpgrade-BeforeYouUpgrade">Before You
Upgrade</h2><ol><li><strong>Check Java version compatibility: </strong>See the
compatibility matrix at <strong><a
href="supported-environments-and-versions.html">Supported Environments and
Versions</a></strong>.<strong><br clear="none"></strong></li><li><strong>Check
3rd Party compatibility:</strong> Find out whether your 3rd party modules are
compatible with the new version of Tapestry. Although the Tapestry developers
try very hard to maintain backward compatibility across versions, sometimes an
older version of a 3rd party module (particularly if it uses internal APIs)
won't work with a newly-released version of T
apestry, and in that case you may have to wait until that 3rd party module is
updated by its developers.</li><li><strong>Find and replace all calls to
deprecated APIs.</strong> Those are the places most likely to be broken after
the upgrade. Most IDEs make it easy to find all deprecated items. In Eclipse,
for example, the "Problems" view will show warnings for the use of deprecated
APIs if you set it to show "All Errors/Warnings on
Project".</li><li><strong>Read the Release Notes:</strong> Each Tapestry
version has a <a href="release-notes.html">Release Notes</a> document that
lists all of the changes, including some that may cause compatibility issues
with your current code. You will save yourself a lot of frustration if you
carefully read this material before proceeding.</li></ol><h2
id="HowtoUpgrade-Upgrading">Upgrading</h2><ol><li><strong>Upgrade one step at a
time:</strong> It is usually best to upgrade to each intermediate version of
Tapestry rather than skipping ahead multip
le versions. Skipping versions (except for minor bug fix releases) makes it
harder to find all calls to deprecated APIs (see above).</li><li><strong>Update
your POM (or download the JARs manually):</strong> If you're using Maven (or
Gradle), update the version of the Tapestry dependencies in your pom.xml (or
build.gradle) file. Remember to keep all of the Tapestry-supplied modules in
sync. For example, don't forget to update the version of Tapestry-hibernate,
Tapestry-spring, Tapestry-upload, etc.</li><li><strong>Remove old Tapestry
JARs:</strong> If you're not using Maven or Gradle (e.g. if you have the
Tapestry JARs in your lib directory), be sure you remove older versions of
Tapestry JARs (including JARs for any Tapestry-supplied modules).</li></ol><h2
id="HowtoUpgrade-AfterYouUpgrade">After You Upgrade</h2><ol><li><strong>Remove
cached JavaScript:</strong> Tapestry's internal JavaScript may change between
releases, and your web browser may have cached the older version (especial
ly for Tapestry versions <em>prior to 5.4)</em>. If you have set a specific <a
href="configuration.html">application version</a> in your application's module
class (usually AppModule.java), you should increment it to ensure that the URLs
to the JavaScript files will have a new version number in their paths. Doing so
will cause the browser to download the latest versions from your server.
Alternatively, you can just clear your browser's cache (and have all your
developers and testers do the same). <em>This issue is usually not a problem on
production servers, since you will likely increment the application version
with each new production release. Also, starting in Tapestry 5.4 this is
unlikely to be a problem due to file checksums being included in their URLs.<br
clear="none"></em></li></ol><p></p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/injection-faq.html
==============================================================================
--- websites/production/tapestry/content/injection-faq.html (original)
+++ websites/production/tapestry/content/injection-faq.html Mon Feb 19 19:21:08
2018
@@ -77,7 +77,14 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="InjectionFAQ-Injection">Injection</h2><p>Main article: <a
href="injection-faq.html">Injection FAQ</a></p><h3
id="InjectionFAQ-What'sthedifferencebetweenthe@Componentand@InjectComponentannotations?">What's
the difference between the <code>@Component</code> and
<code>@InjectComponent</code> annotations?</h3><p>The <code>@Component</code>
annotation is used to define the <em>type</em> of component, and its parameter
bindings. When using <code>@Component</code>, the template must not define the
type, and any parameter bindings are merged in:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+ <div id="ConfluenceContent"><h1
id="InjectionFAQ-Injection">Injection</h1><p>Main article:  <a
href="injection.html">Injection</a></p><h2
id="InjectionFAQ-Contents">Contents</h2><p><style type="text/css">/*<![CDATA[*/
+div.rbtoc1519068035434 {padding: 0px;}
+div.rbtoc1519068035434 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068035434 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068035434">
+<ul class="toc-indentation"><li><a
href="#InjectionFAQ-What'sthedifferencebetweenthe@Componentand@InjectComponentannotations?">What's
the difference between the @Component and @InjectComponent
annotations?</a></li><li><a
href="#InjectionFAQ-What'sthedifferencebetweenthe@InjectPageand@InjectContainerannotations?">What's
the difference between the @InjectPage and @InjectContainer
annotations?</a></li><li><a
href="#InjectionFAQ-IgetanexceptionbecauseIhavetwoserviceswiththesameinterface,howdoIhandlethis?">I
get an exception because I have two services with the same interface, how do I
handle this?</a></li><li><a
href="#InjectionFAQ-What'sthedifferencebetween@Injectand@Environmental?">What's
the difference between @Inject and @Environmental?</a></li><li><a
href="#InjectionFAQ-Butwait...IseeIusedthe@Injectannotationanditstillworked.Whatgives?">But
wait ... I see I used the @Inject annotation and it still worked. What
gives?</a></li><li><a href="#InjectionFAQ-Ok,butRequestisasingleto
nservice,notanenvironmental,andIcaninjectthat.IsTapestryreallythreadsafe?">Ok,
but Request is a singleton service, not an environmental, and I can inject
that. Is Tapestry really thread safe?</a></li><li><a
href="#InjectionFAQ-Iuse@Injectonafieldtoinjectaservice,butthefieldisstillnull,whathappened?">I
use @Inject on a field to inject a service, but the field is still null, what
happened?</a></li></ul>
+</div><h2
id="InjectionFAQ-What'sthedifferencebetweenthe@Componentand@InjectComponentannotations?">What's
the difference between the <code>@Component</code> and
<code>@InjectComponent</code> annotations?</h2><p>The <code>@Component</code>
annotation is used to define the <em>type</em> of component, and its parameter
bindings. When using <code>@Component</code>, the template must not define the
type, and any parameter bindings are merged in:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;"> <a t:id="home" class="nav">Back to
home</a>
</pre>
</div></div><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
@@ -91,7 +98,7 @@
<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;"> @InjectComponent
private Form login;
</pre>
-</div></div><p>Again, we're matching the field name to the component id, and
you would get an error if the component is not defined in the template.</p><h3
id="InjectionFAQ-What'sthedifferencebetweenthe@InjectPageand@InjectContainerannotations?">What's
the difference between the <code>@InjectPage</code> and
<code>@InjectContainer</code> annotations?</h3><p>The <code>@InjectPage</code>
annotation is used to inject some page in the application into a field of some
other page. You often see it used from event handler methods:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+</div></div><p>Again, we're matching the field name to the component id, and
you would get an error if the component is not defined in the template.</p><h2
id="InjectionFAQ-What'sthedifferencebetweenthe@InjectPageand@InjectContainerannotations?">What's
the difference between the <code>@InjectPage</code> and
<code>@InjectContainer</code> annotations?</h2><p>The <code>@InjectPage</code>
annotation is used to inject some page in the application into a field of some
other page. You often see it used from event handler methods:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;"> @InjectPage
private ConfirmRegistration confirmRegistration;
@@ -103,7 +110,7 @@
return confirmRegistration;
}
</pre>
-</div></div><p>This code pattern is used to configure peristent properties of
a page before returning it; Tapestry will send a client redirect to the page to
present the data.</p><p><code>@InjectContainer</code> can be used inside a
component or a mixin. In a component, it injects the immediate container of the
component; this is often the top-level page object.</p><p>In a mixin, it
injects the component to which the mixin is attached.</p><h3
id="InjectionFAQ-IgetanexceptionbecauseIhavetwoserviceswiththesameinterface,howdoIhandlethis?">I
get an exception because I have two services with the same interface, how do I
handle this?</h3><p>It's not uncommon to have two or more services that
implement the exact same interface. When you inject, you might start by just
identifying the type of service to inject:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>This code pattern is used to configure peristent properties of
a page before returning it; Tapestry will send a client redirect to the page to
present the data.</p><p><code>@InjectContainer</code> can be used inside a
component or a mixin. In a component, it injects the immediate container of the
component; this is often the top-level page object.</p><p>In a mixin, it
injects the component to which the mixin is attached.</p><h2
id="InjectionFAQ-IgetanexceptionbecauseIhavetwoserviceswiththesameinterface,howdoIhandlethis?">I
get an exception because I have two services with the same interface, how do I
handle this?</h2><p>It's not uncommon to have two or more services that
implement the exact same interface. When you inject, you might start by just
identifying the type of service to inject:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;"> @Inject
private ComponentEventResultProcessor processor;
</pre>
@@ -125,7 +132,7 @@
@Traditional @Primary
private ComponentEventResultProcessor processor;
</pre>
-</div></div><p>The two marker annotations, <code>@Traditional</code> and
<code>@Primary</code>, ensure that only a single service matches.</p><h3
id="InjectionFAQ-What'sthedifferencebetween@Injectand@Environmental?">What's
the difference between <code>@Inject</code> and
<code>@Environmental</code>?</h3><p><code>@Inject</code> is relatively general;
it can be used to inject resources specific to a page or component (such as
ComponentResources, Logger, or Messages), or it can inject services or other
objects obtained from the Tapestry IoC container. Once the page is loaded, the
values for these injections never change.</p><p><code>@Environmental</code> is
different; it exposes a request-scoped, dynamically bound
value:</p><ul><li>"Request scoped": different threads (processing different
requests) will see different values when reading the
field.</li><li>"Dynamically bound": the value is explicitly placed into the
Environment, and can be overridden at any time.</li></ul><p>Environmenta
ls are a form of loosely connected communication between an outer component
(or even a service) and an inner component. Example: the Form component places
a <code>FormSupport</code> object into the environment. Other components, such
as TextField, use the <code>FormSupport</code> when rendering to perform
functions such as allocate unique control names or register client-side
validations. The TextField doesn't require that the Form component be the
immediate container component, or even an ancestor: a Form on one page may,
indirectly, communicate with a TextField on some entirely different page.
Neither component directly links to the other, the <code>FormSupport</code> is
the conduit that connects them.</p><p>The term "Environmental" was chosen as
the value "comes from the environment".</p><h3
id="InjectionFAQ-Butwait...IseeIusedthe@Injectannotationanditstillworked.Whatgives?">But
wait ... I see I used the <code>@Inject</code> annotation and it still worked.
What gives?</h3><p>In c
ertain cases, Tapestry exposes a service (which can be injected) that is a
proxy to the environmental; this is primarily for common environmentals, such
as <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>,
that may be needed outside of component classes. You can see this in
TapestryModule:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>TapestryModule.java (partial)</b></div><div class="codeContent
panelContent pdl">
+</div></div><p>The two marker annotations, <code>@Traditional</code> and
<code>@Primary</code>, ensure that only a single service matches.</p><h2
id="InjectionFAQ-What'sthedifferencebetween@Injectand@Environmental?">What's
the difference between <code>@Inject</code> and
<code>@Environmental</code>?</h2><p><code>@Inject</code> is relatively general;
it can be used to inject resources specific to a page or component (such as
ComponentResources, Logger, or Messages), or it can inject services or other
objects obtained from the Tapestry IoC container. Once the page is loaded, the
values for these injections never change.</p><p><code>@Environmental</code> is
different; it exposes a request-scoped, dynamically bound
value:</p><ul><li>"Request scoped": different threads (processing different
requests) will see different values when reading the
field.</li><li>"Dynamically bound": the value is explicitly placed into the
Environment, and can be overridden at any time.</li></ul><p>Environmenta
ls are a form of loosely connected communication between an outer component
(or even a service) and an inner component. Example: the Form component places
a <code>FormSupport</code> object into the environment. Other components, such
as TextField, use the <code>FormSupport</code> when rendering to perform
functions such as allocate unique control names or register client-side
validations. The TextField doesn't require that the Form component be the
immediate container component, or even an ancestor: a Form on one page may,
indirectly, communicate with a TextField on some entirely different page.
Neither component directly links to the other, the <code>FormSupport</code> is
the conduit that connects them.</p><p>The term "Environmental" was chosen as
the value "comes from the environment".</p><h2
id="InjectionFAQ-Butwait...IseeIusedthe@Injectannotationanditstillworked.Whatgives?">But
wait ... I see I used the <code>@Inject</code> annotation and it still worked.
What gives?</h2><p>In c
ertain cases, Tapestry exposes a service (which can be injected) that is a
proxy to the environmental; this is primarily for common environmentals, such
as <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>,
that may be needed outside of component classes. You can see this in
TapestryModule:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>TapestryModule.java (partial)</b></div><div class="codeContent
panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> /**
* Builds a proxy to the current {@link JavaScriptSupport} inside this
thread's {@link Environment}.
*
@@ -136,13 +143,13 @@
return environmentalBuilder.build(JavaScriptSupport.class);
}
</pre>
-</div></div><p>This kind of logic is based on the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/EnvironmentalShadowBuilder.html">EnvironmentalShadowBuilder</a>
service.</p><h3
id="InjectionFAQ-Ok,butRequestisasingletonservice,notanenvironmental,andIcaninjectthat.IsTapestryreallythreadsafe?">Ok,
but Request is a singleton service, not an environmental, and I can inject
that. Is Tapestry really thread safe?</h3><p>Yes, of course Tapestry is thread
safe. The Request service is another special case, as seen in
TapestryModule:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>TapestryModule.java (partial)</b></div><div class="codeContent
panelContent pdl">
+</div></div><p>This kind of logic is based on the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/EnvironmentalShadowBuilder.html">EnvironmentalShadowBuilder</a>
service.</p><h2
id="InjectionFAQ-Ok,butRequestisasingletonservice,notanenvironmental,andIcaninjectthat.IsTapestryreallythreadsafe?">Ok,
but Request is a singleton service, not an environmental, and I can inject
that. Is Tapestry really thread safe?</h2><p>Yes, of course Tapestry is thread
safe. The Request service is another special case, as seen in
TapestryModule:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>TapestryModule.java (partial)</b></div><div class="codeContent
panelContent pdl">
<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> public Request buildRequest()
{
return shadowBuilder.build(requestGlobals, "request", Request.class);
}
</pre>
-</div></div><p><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestGlobals.html">RequestGlobals</a>
is a per-thread service. The Request service is a global singleton created by
the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/PropertyShadowBuilder.html">PropertyShadowBuilder</a>
service, but is just a proxy. It has no internal state; invoking a method on
the Request service just turns around and extracts the Request object from the
per-thread RequestGlobals and invokes the same method there.</p><h3
id="InjectionFAQ-Iuse@Injectonafieldtoinjectaservice,butthefieldisstillnull,whathappened?">I
use <code>@Inject</code> on a field to inject a service, but the field is
still null, what happened?</h3><p>This can happen when you use the wrong
<code>@Inject</code> annotation; for example, com.google.inject.Inject instead
of org.apache.tapestry5.ioc.annotations.Inject. T
his can occur when you have TestNG on the classpath, for example, and your IDE
is too helpful. Double check your imports when things seem weird.</p><p>Also
remember that <code>@Inject</code> on fields works for components and for
service implementations or other objects that Tapestry instantiates, but not on
arbitrary objects (that are created via Java's new keyword).</p></div>
+</div></div><p><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/RequestGlobals.html">RequestGlobals</a>
is a per-thread service. The Request service is a global singleton created by
the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/PropertyShadowBuilder.html">PropertyShadowBuilder</a>
service, but is just a proxy. It has no internal state; invoking a method on
the Request service just turns around and extracts the Request object from the
per-thread RequestGlobals and invokes the same method there.</p><h2
id="InjectionFAQ-Iuse@Injectonafieldtoinjectaservice,butthefieldisstillnull,whathappened?">I
use <code>@Inject</code> on a field to inject a service, but the field is
still null, what happened?</h2><p>This can happen when you use the wrong
<code>@Inject</code> annotation; for example, com.google.inject.Inject instead
of org.apache.tapestry5.ioc.annotations.Inject. T
his can occur when you have TestNG on the classpath, for example, and your IDE
is too helpful. Double check your imports when things seem weird.</p><p>Also
remember that <code>@Inject</code> on fields works for components and for
service implementations or other objects that Tapestry instantiates, but not on
arbitrary objects (that are created via Java's new keyword).</p></div>
</div>
<div class="clearer"></div>
Modified:
websites/production/tapestry/content/integration-with-existing-applications.html
==============================================================================
---
websites/production/tapestry/content/integration-with-existing-applications.html
(original)
+++
websites/production/tapestry/content/integration-with-existing-applications.html
Mon Feb 19 19:21:08 2018
@@ -77,8 +77,15 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="Integrationwithexistingapplications-Integrationwithexistingapplications">Integration
with existing applications</h2><p>You may have an existing JSP (or Struts,
Spring MVC, etc.) application that you want to migrate to Tapestry. It's quite
common to do this in stages, moving some functionality into Tapestry and
leaving other parts, initially, in the other system. <a
href="integration-with-existing-applications.html">You may need to prevent
Tapestry from handling certain requests</a>.</p><h3
id="Integrationwithexistingapplications-HowdoImakeaformonaJSPsubmitintoTapestry?">How
do I make a form on a JSP submit into Tapestry?</h3><p>Tapestry's Form
component does a lot of work while an HTML form is rendering to store all the
information needed to handle the form submission in a later request; this is
all very specific to Tapestry and the particular construction of your pages and
forms; it can't be reproduced from a JSP.</p><p>Fortunate
ly, that isn't necessary: you can have a standard HTML Form submit to a
Tapestry page, you just don't get to use all of Tapestry's built in conversion
and validation logic.</p><p>All you need to know is how Tapestry converts page
class names to page names (that appear in the URL). It's basically a matter of
stripping off the <em>root-package</em>.<code>pages</code> prefix from the
fully qualified class name. So, for example, if you are building a login screen
as a JSP, you might want to have a Tapestry page to receive the user name and
password. Let's assume the Tapestry page class is
<code>com.example.myapp.pages.LoginForm</code>; the page name will be
<code>loginform (although, since </code><span>Tapestry is case
insensitive, LoginForm would work just as well)</span><span>, and the URL will
be </span><code>/loginform</code><span>.</span></p><p> </p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;"><form method="post" action="/loginform">
+ <div id="ConfluenceContent"><h1
id="Integrationwithexistingapplications-Integrationwithexistingapplications">Integration
with existing applications</h1><h2
id="Integrationwithexistingapplications-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
+div.rbtoc1519068036085 {padding: 0px;}
+div.rbtoc1519068036085 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068036085 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068036085">
+<ul class="toc-indentation"><li><a
href="#Integrationwithexistingapplications-HowdoImakeaformonaJSPsubmitintoTapestry?">How
do I make a form on a JSP submit into Tapestry?</a></li><li><a
href="#Integrationwithexistingapplications-HowdoIshareinformationbetweenaJSPapplicationandtheTapestryapplication?">How
do I share information between a JSP application and the Tapestry
application?</a></li><li><a
href="#Integrationwithexistingapplications-HowdoIputtheTapestryapplicationinsideafolder,toavoidconflicts?">How
do I put the Tapestry application inside a folder, to avoid
conflicts?</a></li></ul>
+</div><p>You may have an existing JSP (or Struts, Spring MVC, etc.)
application that you want to migrate to Tapestry. It's quite common to do this
in stages, moving some functionality into Tapestry and leaving other parts,
initially, in the other system. <a href="request-processing-faq.html">You may
need to prevent Tapestry from handling certain requests</a>.</p><h2
id="Integrationwithexistingapplications-HowdoImakeaformonaJSPsubmitintoTapestry?">How
do I make a form on a JSP submit into Tapestry?</h2><p>Tapestry's Form
component does a lot of work while an HTML form is rendering to store all the
information needed to handle the form submission in a later request; this is
all very specific to Tapestry and the particular construction of your pages and
forms; it can't be reproduced from a JSP.</p><p>Fortunately, that isn't
necessary: you can have a standard HTML Form submit to a Tapestry page, you
just don't get to use all of Tapestry's built in conversion and validation
logic.</p><p
>All you need to know is how Tapestry converts page class names to page names
>(that appear in the URL). It's basically a matter of stripping off the
><em>root-package</em>.<code>pages</code> prefix from the fully qualified
>class name. So, for example, if you are building a login screen as a JSP, you
>might want to have a Tapestry page to receive the user name and password.
>Let's assume the Tapestry page class is
><code>com.example.myapp.pages.LoginForm</code>; the page name will be
><code>loginform (although, since </code><span>Tapestry is case
>insensitive, LoginForm would work just as well)</span><span>, and the URL
>will be </span><code>/loginform</code><span>.</span></p><p> </p><div
>class="code panel pdl" style="border-width: 1px;"><div class="codeHeader
>panelHeader pdl" style="border-bottom-width:
>1px;"><b>LoginForm.tml</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><form method="post" action="/loginform">
<input type="text" value="userName"/>
<br/>
@@ -88,8 +95,8 @@
</form>
</pre>
-</div></div><p>On the Tapestry side, we can expect that the LoginForm page
will be activated; this means that its activate event handler will be invoked.
We can leverage this, and Tapestry's RequestParameter annotation:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;">public class LoginForm
+</div></div><p>On the Tapestry side, we can expect that the LoginForm page
will be activated; this means that its activate event handler will be invoked.
We can leverage this, and Tapestry's RequestParameter annotation:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader
panelHeader pdl" style="border-bottom-width:
1px;"><b>LoginForm.java</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class LoginForm
{
void onActivate(@RequestParameter("userName") String userName,
@RequestParameter("password") String password)
{
@@ -97,14 +104,14 @@
}
}
</pre>
-</div></div><p>The RequestParameter annotation extracts the named query
parameter from the request, coerces its type from String to the parameter type
(here, also String) and passes it into the method.</p><h3
id="Integrationwithexistingapplications-HowdoIshareinformationbetweenaJSPapplicationandtheTapestryapplication?">How
do I share information between a JSP application and the Tapestry
application?</h3><p>From the servlet container's point of view, there's no
difference between a servlet, a JSP, and an entire Tapestry application. They
all share the same ServletContext, and (once created), the same
HttpSession.</p><p>On the Tapestry side, it is very easy to read and write
session attributes:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;">public class ShowSearchResults
+</div></div><p>The RequestParameter annotation extracts the named query
parameter from the request, coerces its type from String to the parameter type
(here, also String) and passes it into the method.</p><h2
id="Integrationwithexistingapplications-HowdoIshareinformationbetweenaJSPapplicationandtheTapestryapplication?">How
do I share information between a JSP application and the Tapestry
application?</h2><p>From the servlet container's point of view, there's no
difference between a servlet, a JSP, and an entire Tapestry application. They
all share the same ServletContext, and (once created), the same
HttpSession.</p><p>On the Tapestry side, it is very easy to read and write
session attributes:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>ShowSearchResults.java</b></div><div class="codeContent panelContent
pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class ShowSearchResults
{
@SessionAttribute
private SearchResults searchResults;
}
</pre>
-</div></div><p>Reading the instance variable <code>searchResults</code> is
instrumented to instead read the corresponding HttpSession attribute named
"searchResults". You can also specify the <code>value</code> attribute of the
SessionAttribute annotation to override the default attribute
name.</p><p>Writing to the field causes the corresponding HttpSession attribute
to be modified.</p><p>The session is automatically created as needed.</p><h3
id="Integrationwithexistingapplications-HowdoIputtheTapestryapplicationinsideafolder,toavoidconflicts?">How
do I put the Tapestry application inside a folder, to avoid
conflicts?</h3><p>Support for this was added in 5.3; see the notes on the <a
href="integration-with-existing-applications.html">configuration
page</a>. </p><p> </p><p> </p></div>
+</div></div><p>Reading the instance variable <code>searchResults</code> is
instrumented to instead read the corresponding HttpSession attribute named
"searchResults". You can also specify the <code>value</code> attribute of the
SessionAttribute annotation to override the default attribute
name.</p><p>Writing to the field causes the corresponding HttpSession attribute
to be modified.</p><p>The session is automatically created as needed.</p><h2
id="Integrationwithexistingapplications-HowdoIputtheTapestryapplicationinsideafolder,toavoidconflicts?">How
do I put the Tapestry application inside a folder, to avoid
conflicts?</h2><p>Support for this was added in 5.3; see the notes on the <a
href="configuration.html">configuration
page</a>. </p><p> </p><p> </p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/javascript-faq.html
==============================================================================
--- websites/production/tapestry/content/javascript-faq.html (original)
+++ websites/production/tapestry/content/javascript-faq.html Mon Feb 19
19:21:08 2018
@@ -77,7 +77,14 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="JavaScriptFAQ-JavaScript">JavaScript</h2><p>Main article: <a
href="javascript-faq.html">JavaScript FAQ</a></p><h3
id="JavaScriptFAQ-WhydoIgeta"Tapestryisundefined"erroronformsubmit?(5.3andearlier)">Why
do I get a "Tapestry is undefined" error on form submit? (5.3 and
earlier)</h3><p>This client-side error is clear but can be awkward to solve. It
means your browser has not been able to load the tapestry.js file properly. The
question is, why? It can be due to multiple reasons, some of them
below:</p><ul><li>First, check if 'tapestry.js' is present in the head part of
your resulting HTML page.</li><li><p>If you have set the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/SymbolConstants.html#COMBINE_SCRIPTS">tapestry.combine-scripts</a>
configuration symbol to true, Tapestry generates one single URL to retrieve
all the JS files. Sometimes, this can produce long URLs that brow
sers are unable to retrieve. Try setting the symbol to false.</p><div
class="confluence-information-macro confluence-information-macro-note"><span
class="aui-icon aui-icon-small aui-iconfont-warning
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>This only applies to Tapestry
5.1.</p></div></div></li><li>If you have included jQuery in conjunction with
Tapestry's prototype, that will cause a conflict with the '$' selector used by
both. In this case, you should put jQuery on top of the stack and turn on the
<a class="external-link" href="http://api.jquery.com/jQuery.noConflict/"
rel="nofollow">jQuery.noConflict</a> mode.</li><li>Also, if you have included a
custom or third-party JS library on top of the stack that causes the JavaScript
parsing to fail, then check the JavaScript syntax in that library.</li><li>If
you have used a tool to minimize your JavaScript libraries, this can lead to
JavaScript syntax errors, so check if it works with a
ll the JavaScript files unpacked.</li></ul><h3
id="JavaScriptFAQ-What'sthedifferencebetweentheT5objectandtheTapestryobjectinthebrowser?(5.3andearlier)">What's
the difference between the <code>T5</code> object and the
<code>Tapestry</code> object in the browser? (5.3 and earlier)</h3><p>Both of
these objects are <em>namespaces</em>: containers of functions, constants, and
nested namespaces.</p><p>The <code>T5</code> object is a replacement for the
<code>Tapestry</code> object, starting in release 5.3. Increasingly, functions
defined by the <code>Tapestry</code> object are being replaced with similar or
equivalent functions in the <code>T5</code> object.</p><p>This is part of an
overall goal, spanning at least two releases of Tapestry, to make Tapestry
JavaScript framework agnostic; which is to say, not depend specifically on
Prototype or jQuery. Much of the code in the <code>Tapestry</code> object is
specifically linked to Prototype and Scriptaculous.</p><p>The <code>T5</code>
object
represents a stable, documented, set of APIs that are preferred when building
components for maximum portability between underlying JavaScript frameworks. In
other words, when building component libraries, coding to the <code>T5</code>
object ensures that your component will be useful regardless of whether the
final application is built using Prototype, jQuery or something else.</p></div>
+ <div id="ConfluenceContent"><h1
id="JavaScriptFAQ-JavaScript">JavaScript</h1><p>Main articles: <a
href="client-side-javascript.html">Client-Side JavaScript</a>, <a
href="legacy-javascript.html">Legacy JavaScript</a></p><h2
id="JavaScriptFAQ-Contents">Contents</h2><p><style type="text/css">/*<![CDATA[*/
+div.rbtoc1519068037696 {padding: 0px;}
+div.rbtoc1519068037696 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519068037696 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519068037696">
+<ul class="toc-indentation"><li><a
href="#JavaScriptFAQ-WhydoIgeta"Tapestryisundefined"erroronformsubmit?(5.3andearlier)">Why
do I get a "Tapestry is undefined" error on form submit? (5.3 and
earlier)</a></li><li><a
href="#JavaScriptFAQ-What'sthedifferencebetweentheT5objectandtheTapestryobjectinthebrowser?(5.3andearlier)">What's
the difference between the T5 object and the Tapestry object in the browser?
(5.3 and earlier)</a></li></ul>
+</div><h2
id="JavaScriptFAQ-WhydoIgeta"Tapestryisundefined"erroronformsubmit?(5.3andearlier)">Why
do I get a "Tapestry is undefined" error on form submit? (5.3 and
earlier)</h2><p>This client-side error is clear but can be awkward to solve. It
means your browser has not been able to load the tapestry.js file properly. The
question is, why? It can be due to multiple reasons, some of them
below:</p><ul><li>First, check if 'tapestry.js' is present in the head part of
your resulting HTML page.</li><li><p>If you have set the <a
href="configuration.html">tapestry.combine-scripts</a> configuration symbol to
true, Tapestry generates one single URL to retrieve all the JS files.
Sometimes, this can produce long URLs that browsers are unable to retrieve. Try
setting the symbol to false.</p><div class="confluence-information-macro
confluence-information-macro-note"><span class="aui-icon aui-icon-small
aui-iconfont-warning confluence-information-macro-icon"></span><div
class="confluen
ce-information-macro-body"><p>This only applies to Tapestry
5.1.</p></div></div></li><li>If you have included jQuery in conjunction with
Tapestry's prototype, that will cause a conflict with the '$' selector used by
both. In this case, you should put jQuery on top of the stack and turn on the
<a class="external-link" href="http://api.jquery.com/jQuery.noConflict/"
rel="nofollow">jQuery.noConflict</a> mode.</li><li>Also, if you have included a
custom or third-party JS library on top of the stack that causes the JavaScript
parsing to fail, then check the JavaScript syntax in that library.</li><li>If
you have used a tool to minimize your JavaScript libraries, this can lead to
JavaScript syntax errors, so check if it works with all the JavaScript files
unpacked.</li></ul><h2
id="JavaScriptFAQ-What'sthedifferencebetweentheT5objectandtheTapestryobjectinthebrowser?(5.3andearlier)">What's
the difference between the <code>T5</code> object and the
<code>Tapestry</code> object in the browser?
(5.3 and earlier)</h2><p>Both of these objects are <em>namespaces</em>:
containers of functions, constants, and nested namespaces.</p><p>The
<code>T5</code> object is a replacement for the <code>Tapestry</code> object,
starting in release 5.3. Increasingly, functions defined by the
<code>Tapestry</code> object are being replaced with similar or equivalent
functions in the <code>T5</code> object.</p><p>This is part of an overall goal,
spanning at least two releases of Tapestry, to make Tapestry JavaScript
framework agnostic; which is to say, not depend specifically on Prototype or
jQuery. Much of the code in the <code>Tapestry</code> object is specifically
linked to Prototype and Scriptaculous.</p><p>The <code>T5</code> object
represents a stable, documented, set of APIs that are preferred when building
components for maximum portability between underlying JavaScript frameworks. In
other words, when building component libraries, coding to the <code>T5</code>
object ensures that your
component will be useful regardless of whether the final application is built
using Prototype, jQuery or something else.</p></div>
</div>
<div class="clearer"></div>