Author: buildbot
Date: Mon Feb 19 18:20:23 2018
New Revision: 1025613
Log:
Production update by buildbot for tapestry
Modified:
websites/production/tapestry/content/beaneditform-faq.html
websites/production/tapestry/content/cache/main.pageCache
websites/production/tapestry/content/forms-and-form-components-faq.html
websites/production/tapestry/content/general-questions.html
websites/production/tapestry/content/page-and-component-classes-faq.html
websites/production/tapestry/content/templating-and-markup-faq.html
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
18:20:23 2018
@@ -77,7 +77,14 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="BeanEditFormFAQ-BeanEditForm">BeanEditForm</h2><h3
id="BeanEditFormFAQ-WhydoIgetexceptionsaboutinstantiatingabeanwhenusingBeanEditForm?">Why
do I get exceptions about instantiating a bean when using
BeanEditForm?</h3><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="beaneditform-faq.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>Pla
ce an @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/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">
+ <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;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519064398641">
+<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 {
@Inject
public MyBean() { ... }
@@ -101,7 +108,7 @@
}
}
</pre>
-</div></div><h3
id="BeanEditFormFAQ-What'sthedifferencebetweenBeanEditorandBeanEditForm?">What's
the difference between BeanEditor and BeanEditForm?</h3><p>BeanEditor is a
component used within a BeanEditForm. A BeanEditForm simply combines a
BeanEditor, a Form, and a Submit component together. Most of the capabilities
of BeanEditForm are derived from the BeanEditor.</p><h3
id="BeanEditFormFAQ-HowdoIcustomizethelayoutoftheBeanEditForm?">How do I
customize the layout of the BeanEditForm?</h3><p>The BeanEditForm is a
<em>scaffolding</em> component; it exists to get things up and running quickly.
It can be customized visually using CSS, and can be configured and extended in
a number of ways ... but ultimately, if you want fine control, you should use
the underlying Form, TextField and other components directly.</p></div>
+</div></div><h2
id="BeanEditFormFAQ-What'sthedifferencebetweenBeanEditorandBeanEditForm?">What's
the difference between BeanEditor and BeanEditForm?</h2><p>BeanEditor is a
component used within a BeanEditForm. A BeanEditForm simply combines a
BeanEditor, a Form, and a Submit component together. Most of the capabilities
of BeanEditForm are derived from the BeanEditor.</p><h2
id="BeanEditFormFAQ-HowdoIcustomizethelayoutoftheBeanEditForm?">How do I
customize the layout of the BeanEditForm?</h2><p>The BeanEditForm is a
<em>scaffolding</em> component; it exists to get things up and running quickly.
It can be customized visually using CSS, and can be configured and extended in
a number of ways ... but ultimately, if you want fine control, you should use
the underlying Form, TextField and other components directly.</p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.
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 18:20:23 2018
@@ -77,7 +77,14 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="FormsandFormComponentsFAQ-FormsandFormComponents">Forms and Form
Components</h2><p>Main article: <a
href="forms-and-form-components-faq.html">Forms and Form Components
FAQ</a></p><h3
id="FormsandFormComponentsFAQ-Whatisthet:formdatahiddenfieldfor?">What is the
<code>t:formdata</code> hidden field for?</h3><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">
+ <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;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519064398334">
+<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
{
/**
@@ -96,7 +103,7 @@
*/
<T> void storeAndExecute(T component, ComponentAction<T>
action);
</pre>
-</div></div><p>The <code>ComponentAction</code> objects are the callbacks.
<code>t:formdata</code> is simply an object stream of these callbacks,
compressed and encoded in Base64. When using Ajax, you may see multiple
<code>t:formdata</code> hidden fields (they are processed one after
another).</p><h3
id="FormsandFormComponentsFAQ-HowdoIchangethelabelforafieldonthefly?">How do I
change the label for a field on the fly?</h3><p>Tapestry tries to be smart
about generating the label string for a field. It has some smart default logic,
first checking for the <em>component-id</em><code>-label</code> in the
container's message catalog, then ultimately converting the component's id into
a user-presentable label.</p><p>You can override the label in two
ways:</p><p>First, you can supply a body to the <code>Label</code>
component:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+</div></div><p>The <code>ComponentAction</code> objects are the callbacks.
<code>t:formdata</code> is simply an object stream of these callbacks,
compressed and encoded in Base64. When using Ajax, you may see multiple
<code>t:formdata</code> hidden fields (they are processed one after
another).</p><h2
id="FormsandFormComponentsFAQ-HowdoIchangethelabelforafieldonthefly?">How do I
change the label for a field on the fly?</h2><p>Tapestry tries to be smart
about generating the label string for a field. It has some smart default logic,
first checking for the <em>component-id</em><code>-label</code> in the
container's message catalog, then ultimately converting the component's id into
a user-presentable label.</p><p>You can override the label in two
ways:</p><p>First, you can supply a body to the <code>Label</code>
component:</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;"> <t:label
for="username">${usernameLabel}</t:label>
<t:textfield t:id="username"/>
</pre>
@@ -110,7 +117,7 @@
<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;"> <t:label for="username"/>
<t:textfield t:id="username" label="prop:usernameLabel"/>
</pre>
-</div></div><p>The "prop:" prefix identifies that "usernameLabel" is to be
interpreted as a property expression (normally, the binding for the
<code>label</code> parameter is interpreted as a string literal). The Label
component gets the text it displays from the TextField component, and the
TextField component uses the same text when generating server-side and
client-side validation messages.</p><h3
id="FormsandFormComponentsFAQ-Tapestryfocusesonthewrongfieldinmyform,howdoIfixthat?">Tapestry
focuses on the wrong field in my form, how do I fix that?</h3><p>Tapestry
normally figures out the correct field in your form to initially receive focus;
this is based on assigning a <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/FieldFocusPriority.html">FieldFocusPriority</a>
to each field as it renders, which works out to the following
logic:</p><ul><li>The first field which has an error</li><li>Or, the first
field which is required</li><li>Or,
the first field</li></ul><p>Occasionally, due a wide range of factors beyond
Tapestry's control, it's selection will not be quite what you want, and it is
necessary to supply an override. The information is tracked inside the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>
environmental. It's just a matter of injecting the component so that you can
determine its client id, then informing JavaScriptSupport about your
override.</p><p>Here's an example</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+</div></div><p>The "prop:" prefix identifies that "usernameLabel" is to be
interpreted as a property expression (normally, the binding for the
<code>label</code> parameter is interpreted as a string literal). The Label
component gets the text it displays from the TextField component, and the
TextField component uses the same text when generating server-side and
client-side validation messages.</p><h2
id="FormsandFormComponentsFAQ-Tapestryfocusesonthewrongfieldinmyform,howdoIfixthat?">Tapestry
focuses on the wrong field in my form, how do I fix that?</h2><p>Tapestry
normally figures out the correct field in your form to initially receive focus;
this is based on assigning a <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/FieldFocusPriority.html">FieldFocusPriority</a>
to each field as it renders, which works out to the following
logic:</p><ul><li>The first field which has an error</li><li>Or, the first
field which is required</li><li>Or,
the first field</li></ul><p>Occasionally, due a wide range of factors beyond
Tapestry's control, it's selection will not be quite what you want, and it is
necessary to supply an override. The information is tracked inside the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html">JavaScriptSupport</a>
environmental. It's just a matter of injecting the component so that you can
determine its client id, then informing JavaScriptSupport about your
override.</p><p>Here's an 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;"> <t:textfield t:id="email"
t:mixins="OverrideFieldFocus" .../>
</pre>
</div></div><p>The <a class="external-link"
href="http://tapestry.apache.org/5.4/apidocs/org/apache/tapestry5/corelib/mixins/OverrideFieldFocus.html">OverrideFieldFocus</a>
mixin forces the email field to be the focus field, regardless.</p></div>
Modified: websites/production/tapestry/content/general-questions.html
==============================================================================
--- websites/production/tapestry/content/general-questions.html (original)
+++ websites/production/tapestry/content/general-questions.html Mon Feb 19
18:20:23 2018
@@ -77,16 +77,14 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="GeneralQuestions-GeneralQuestions">General Questions</h2><p><style
type="text/css">/*<![CDATA[*/
-div.rbtoc1518405691837 {padding: 0px;}
-div.rbtoc1518405691837 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1518405691837 li {margin-left: 0px;padding-left: 0px;}
+ <div id="ConfluenceContent"><h1
id="GeneralQuestions-GeneralQuestions">General Questions</h1><h2
id="GeneralQuestions-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
+div.rbtoc1519064397390 {padding: 0px;}
+div.rbtoc1519064397390 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519064397390 li {margin-left: 0px;padding-left: 0px;}
-/*]]>*/</style></p><div class="toc-macro rbtoc1518405691837">
-<ul class="toc-indentation"><li><a
href="#GeneralQuestions-GeneralQuestions">General Questions</a>
-<ul class="toc-indentation"><li><a
href="#GeneralQuestions-HowdoIgetstartedwithTapestry?">How do I get started
with Tapestry?</a></li><li><a
href="#GeneralQuestions-WhydoesTapestryusePrototype?WhynotinsertfavoriteJavaScriptlibraryhere?">Why
does Tapestry use Prototype? Why not insert favorite JavaScript library
here?</a></li><li><a
href="#GeneralQuestions-WhydoesTapestryhaveitsownInversionofControlContainer?WhynotSpringorGuice?">Why
does Tapestry have its own Inversion of Control Container? Why not Spring or
Guice?</a></li><li><a
href="#GeneralQuestions-HowdoIupgradefromTapestry4toTapestry5?">How do I
upgrade from Tapestry 4 to Tapestry 5?</a></li><li><a
href="#GeneralQuestions-HowdoIupgradefromoneversionofTapestry5toanother?">How
do I upgrade from one version of Tapestry 5 to another?</a></li></ul>
-</li></ul>
-</div><h3 id="GeneralQuestions-HowdoIgetstartedwithTapestry?">How do I get
started with Tapestry?</h3><p>The easiest way to get started is to use <a
class="external-link" href="http://maven.apache.org">Apache Maven</a> to create
your initial project; Maven can use an <em>archetype</em> (a kind of project
template) to create a bare-bones Tapestry application for you. See the <a
href="general-questions.html">General Questions</a> page for more
details.</p><p>Even without Maven, Tapestry is quite easy to set up. You just
need to <a href="general-questions.html">download</a> the binaries and setup
your build to place them inside your WAR's WEB-INF/lib folder. The rest is just
some one-time <a href="general-questions.html">configuration of the web.xml
deployment descriptor</a>.</p><h3
id="GeneralQuestions-WhydoesTapestryusePrototype?WhynotinsertfavoriteJavaScriptlibraryhere?">Why
does Tapestry use Prototype? Why not <em>insert favorite JavaScript library
here</em>?</h3><p>An importan
t goal for Tapestry is seamless DHTML and Ajax integration. To serve that
goal, it was important that the built in components be capable of Ajax
operations, such as dynamically re-rendering parts of the page. Because of
that, it made sense to bundle a well-known JavaScript library as part of
Tapestry.</p><p>At the time (this would be 2006-ish), Prototype and
Scriptaculous were well known and well documented, and jQuery was just getting
started.</p><p>The intent has always been to make this aspect of Tapestry
pluggable. Tapestry 5.4 includes the option of either Prototype or jQuery
Tapestry 5.5 will remove Prototype as an option..</p><h3
id="GeneralQuestions-WhydoesTapestryhaveitsownInversionofControlContainer?WhynotSpringorGuice?">Why
does Tapestry have its own Inversion of Control Container? Why not Spring or
Guice?</h3><p>An Inversion of Control Container is <em>the</em> key piece of
Tapestry's infrastructure. It is absolutely necessary to create software as
robust, performant ,an
d extensible as Tapestry.</p><p>Tapestry IoC includes a number of features
that distinguish itself from other containers:</p><ul><li>Configured in code,
not XML</li><li>Built-in extension mechanism for services: configurations and
contributions</li><li>Built-in aspect oriented programming model (service
decorations and advice)</li><li>Easy modularization</li><li>Best-of-breed
exception reporting</li></ul><p>Because Tapestry is implemented on top of its
IoC container, and because the container makes it easy to extend or replace any
service inside the container, it is possible to make the small changes to
Tapestry needed to customize it to any project's needs.</p><h3
id="GeneralQuestions-HowdoIupgradefromTapestry4toTapestry5?">How do I upgrade
from Tapestry 4 to Tapestry 5?</h3><p>There is no existing tool that supports
upgrading from Tapestry 4 to Tapestry 5; Tapestry 5 is a complete
rewrite.</p><p>Many of the basic concepts in Tapestry 4 are still present in
Tapestry 5, but refactor
ed, improved, streamlined, and simplified. The basic concept of pages,
templates and components are largely the same. Other aspects, such as
server-side event handling, is markedly different.</p><h3
id="GeneralQuestions-HowdoIupgradefromoneversionofTapestry5toanother?">How do I
upgrade from one version of Tapestry 5 to another?</h3><p>A lot of effort goes
into making an upgrade from one Tapestry 5 release to another go smoothly. In
the general case, it is just a matter of updating the version number in your
Maven <code>build.xml</code> or Gradle <code>build.gradle</code> file and
executing the appropriate commands (e.g., <code>gradle idea</code> or <code>mvn
eclipse:eclipse</code>) to bring your local workspace up to date with the
latest binaries.</p><p>After changing dependencies, you should always perform a
clean recompile of your application.</p><p>We make every effort to ensure
backwards-compatibility. Tapestry is mostly coded in terms of interfaces; those
interfaces are stable
to a point: interfaces your code is expected to implement are usually
completely frozen; interfaces your code is expected to invoke, such as the
interfaces to IoC services, are stable, but may have new methods added in a
release; existing methods are not changed.</p><p>In <em>rare</em> cases a
choice is necessary between fixing bugs (or adding essential functionality) and
maintaining complete backwards compatibility; in those cases, an incompatible
change may be introduced. These are always discussed in detail in the <a
href="general-questions.html">General Questions</a> for the specific release.
You should always read the release notes before attempting an upgrade, and
always (really, <em>always</em>) be prepared to retest your application
afterwards.</p><p>Note that you should be careful any time you make use of
<strong>internal</strong> APIs (you can tell an API is internal by the package
name, <code>org.apache.tapestry5.internal...</code>. Internal APIs may change
<em>at any ti
me</em>; there's no guarantee of backwards compatibility. Please always check
on the documentation, or consult the user mailing list, to see if there's a
stable, public alternative. If you do make use of internal APIs, be sure to get
a discussion going so that your needs can be met in the future by a stable,
public API.</p><p><span style="color: rgb(83,145,38);">Why are there both
Request and HttpServletRequest?</span></p><p>Tapestry's Request interface is
<em>very</em> close to the standard HttpServletRequest interface. It differs in
a few ways, omitting some unneeded methods, and adding a couple of new methods
(such as <code>isXHR()</code>), as well as changing how some existing methods
operate. For example, <code>getParameterNames()</code> returns a sorted List of
Strings; HttpServletRequest returns an Enumeration, which is a very dated
approach.</p><p>However, the stronger reason for Request (and the related
interfaces Response and Session) is to enable the support for Portlets
at some point in the future. By writing code in terms of Tapestry's Request,
and not HttpServletRequest, you can be assured that the same code will operate
in both Servlet Tapestry and Portlet Tapestry.</p></div>
+/*]]>*/</style></p><div class="toc-macro rbtoc1519064397390">
+<ul class="toc-indentation"><li><a
href="#GeneralQuestions-HowdoIgetstartedwithTapestry?">How do I get started
with Tapestry?</a></li><li><a
href="#GeneralQuestions-WhydoesTapestryusePrototype(inversionsbefore5.4)?WhynotinsertfavoriteJavaScriptlibraryhere?">Why
does Tapestry use Prototype (in versions before 5.4)? Why not insert favorite
JavaScript library here?</a></li><li><a
href="#GeneralQuestions-WhydoesTapestryhaveitsownInversionofControlContainer?WhynotSpringorGuice?">Why
does Tapestry have its own Inversion of Control Container? Why not Spring or
Guice?</a></li><li><a
href="#GeneralQuestions-HowdoIupgradefromTapestry4toTapestry5?">How do I
upgrade from Tapestry 4 to Tapestry 5?</a></li><li><a
href="#GeneralQuestions-HowdoIupgradefromoneversionofTapestry5toanother?">How
do I upgrade from one version of Tapestry 5 to another?</a></li><li><a
href="#GeneralQuestions-WhyaretherebothRequestandHttpServletRequest?">Why are
there both Request and HttpServletRequest?</a></li></ul
>
+</div><h2 id="GeneralQuestions-HowdoIgetstartedwithTapestry?">How do I get
started with Tapestry?</h2><p class="confluence-link">The easiest way to get
started is to use <a class="external-link"
href="http://maven.apache.org">Apache Maven</a> to create your initial project;
Maven can use an <em>archetype</em> (a kind of project template) to create a
bare-bones Tapestry application for you. See the <a
href="getting-started.html">Getting Started</a> page for more
details.</p><p>Even without Maven, Tapestry is quite easy to set up. You just
need to <a href="general-questions.html">download</a> the binaries and setup
your build to place them inside your WAR's WEB-INF/lib folder. The rest is just
some one-time <a href="configuration.html">configuration of the web.xml
deployment descriptor</a>.</p><h2
id="GeneralQuestions-WhydoesTapestryusePrototype(inversionsbefore5.4)?WhynotinsertfavoriteJavaScriptlibraryhere?">Why
does Tapestry use Prototype (in versions before 5.4)? Why not <
em>insert favorite JavaScript library here</em>?</h2><p>An important goal for
Tapestry is seamless DHTML and Ajax integration. To serve that goal, it was
important that the built in components be capable of Ajax operations, such as
dynamically re-rendering parts of the page. Because of that, it made sense to
bundle a well-known JavaScript library as part of Tapestry.</p><p>At the time
(this would be 2006-ish), Prototype and Scriptaculous were well known and well
documented, whereas jQuery was just getting started.</p><p>The intent has
always been to make this aspect of Tapestry pluggable. Tapestry 5.4 includes
the option of either Prototype or jQuery, and future versions of Tapestry will
likely remove Prototype as an option..</p><h2
id="GeneralQuestions-WhydoesTapestryhaveitsownInversionofControlContainer?WhynotSpringorGuice?">Why
does Tapestry have its own Inversion of Control Container? Why not Spring or
Guice?</h2><p>An Inversion of Control Container is <em>the</em> key piece of
Tapestry's infrastructure. It is absolutely necessary to create software as
robust, performant and extensible as Tapestry.</p><p>Tapestry IoC includes a
number of features that distinguish itself from other
containers:</p><ul><li>Configured in code, not XML</li><li>Built-in extension
mechanism for services: configurations and contributions</li><li>Built-in
aspect oriented programming model (service decorations and advice)</li><li>Easy
modularization</li><li>Best-of-breed exception reporting</li></ul><p>Because
Tapestry is implemented on top of its IoC container, and because the container
makes it easy to extend or replace any service inside the container, it is
possible to make the small changes to Tapestry needed to customize it to any
project's needs.</p><p>In addition – and this is critical –
Tapestry allows 3rd party libraries to be built that fully participate in the
configurability of Tapestry itself. This means that such libraries can be
configured the same w
ay Tapestry itself is configured, and such libraries can also configure
Tapestry itself. This <em>distributed configuration</em> requires an IOC
container that fully supports such configurability.</p><h2
id="GeneralQuestions-HowdoIupgradefromTapestry4toTapestry5?">How do I upgrade
from Tapestry 4 to Tapestry 5?</h2><p>There is no existing tool that supports
upgrading from Tapestry 4 to Tapestry 5; Tapestry 5 is a complete
rewrite.</p><p>Many of the basic concepts in Tapestry 4 are still present in
Tapestry 5, but refactored, improved, streamlined, and simplified. The basic
concept of pages, templates and components are largely the same. Other aspects,
such as server-side event handling, is markedly different.</p><p>Tapestry 5 is
designed so that it can live side-by-side in the same servlet as a Tapestry 4
app, without package namespace conflicts, sharing session data and common
resources such as images and CSS. This means that you can gradually migrate a
Tapestry 4 app to Tapestry 5
one page (or one portion of the app) at a time.</p><h2
id="GeneralQuestions-HowdoIupgradefromoneversionofTapestry5toanother?">How do I
upgrade from one version of Tapestry 5 to another?</h2><p>Main Article: <a
href="how-to-upgrade.html">How to Upgrade</a>.</p><p>A lot of effort goes into
making an upgrade from one Tapestry 5 release to another go smoothly. In the
general case, it is just a matter of updating the version number in your Maven
<code>build.xml</code> or Gradle <code>build.gradle</code> file and executing
the appropriate commands (e.g., <code>gradle idea</code> or <code>mvn
eclipse:eclipse</code>) to bring your local workspace up to date with the
latest binaries.</p><p>After changing dependencies, you should always perform a
clean recompile of your application.</p><p>We make every effort to ensure
backwards-compatibility. Tapestry is mostly coded in terms of interfaces; those
interfaces are stable to a point: interfaces your code is expected to implement
are usually co
mpletely frozen; interfaces your code is expected to invoke, such as the
interfaces to IoC services, are stable, but may have new methods added in a
release; existing methods are not changed.</p><p>In <em>rare</em> cases a
choice is necessary between fixing bugs (or adding essential functionality) and
maintaining complete backwards compatibility; in those cases, an incompatible
change may be introduced. These are always discussed in detail in the <a
href="release-notes.html">Release Notes</a> for the specific release. You
should always read the release notes before attempting an upgrade, and always
(really, <em>always</em>) be prepared to retest your application
afterwards.</p><p>Note that you should be careful any time you make use of
<strong>internal</strong> APIs (you can tell an API is internal by the package
name, <code>org.apache.tapestry5.internal). </code>Internal APIs may change
<em>at any time</em>; there's no guarantee of backwards compatibility. Please
always check
on the documentation, or consult the user mailing list, to see if there's a
stable, public alternative. If you do make use of internal APIs, be sure to get
a discussion going so that your needs can be met in the future by a stable,
public API.</p><h2
id="GeneralQuestions-WhyaretherebothRequestandHttpServletRequest?"><span
style="color: rgb(83,145,38);">Why are there both Request and
HttpServletRequest?</span></h2><p>Tapestry's Request interface is <em>very</em>
close to the standard HttpServletRequest interface. It differs in a few ways,
omitting some unneeded methods, and adding a couple of new methods (such as
<code>isXHR()</code>), as well as changing how some existing methods operate.
For example, <code>getParameterNames()</code> returns a sorted List of Strings;
HttpServletRequest returns an Enumeration, which is a very dated
approach.</p><p>However, the stronger reason for Request (and the related
interfaces Response and Session) is to enable the support for Portlets at some
point in the future. By writing code in terms of Tapestry's Request, and not
HttpServletRequest, you can be assured that the same code will operate in both
Servlet Tapestry and Portlet Tapestry.</p></div>
</div>
<div class="clearer"></div>
Modified:
websites/production/tapestry/content/page-and-component-classes-faq.html
==============================================================================
--- websites/production/tapestry/content/page-and-component-classes-faq.html
(original)
+++ websites/production/tapestry/content/page-and-component-classes-faq.html
Mon Feb 19 18:20:23 2018
@@ -77,13 +77,20 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="PageAndComponentClassesFAQ-PageAndComponentClasses">Page And Component
Classes</h2><p>Main article: <a
href="page-and-component-classes-faq.html">Page And Component Classes
FAQ</a></p><h3
id="PageAndComponentClassesFAQ-What'sthedifferencebetweenapageandacomponent?">What's
the difference between a page and a component?</h3><p>There's very little
difference between the two. Pages classes must be in the
<em>root-package</em>.<code>pages</code> package; components must be in the
<em>root-package</em>.<code>components</code>. Pages may provide event handlers
for certain page-specific events (such as activate and passivate). Components
may have parameters.</p><p>Other than that, they are more equal than they are
different. They may have templates or may render themselves in code (pages
usually have a template, components are more likely to render only in
code).</p><p>The major difference is that Tapestry page templates may be stored
in
the web context directory, as if they were static files (they can't be
accessed from the client however; a specific rule prevents access to files with
the <code>.tml</code> extension).</p><div class="confluence-information-macro
confluence-information-macro-warning"><span class="aui-icon aui-icon-small
aui-iconfont-error confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>It is possible that this feature
may be removed in a later release. It is preferred that page templates be
stored on the classpath, like component templates.</p></div></div><h3
id="PageAndComponentClassesFAQ-HowdoIstoremypageclassesinadifferentpackage?">How
do I store my page classes in a different package?</h3><p>Tapestry is very
rigid here; you can't. Page classes must go in
<em>root-package</em>.<code>pages</code>, component classes in
<em>root-package</em>.<code>components</code>, etc.</p><p>You are allowed to
create sub-packages, to help organize your code better and mor
e logically. For example, you might have
<em>root-package</em>.<code>pages.account.ViewAccount</code>, which would have
the page name "account/viewaccount". (<span>Tapestry would also create an alias
"account/view", by stripping off the redundant "account" suffix. Either name is
equally valid in your code, and Tapestry will use the shorter name,
"account/view" in URLs.)</span></p><p>In addition, it is possible to define
additional root packages for the application:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+ <div id="ConfluenceContent"><h1
id="PageAndComponentClassesFAQ-PageAndComponentClasses">Page And Component
Classes</h1><p>Main article: <a href="component-classes.html">Component
Classes</a></p><h2
id="PageAndComponentClassesFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
+div.rbtoc1519064397997 {padding: 0px;}
+div.rbtoc1519064397997 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519064397997 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519064397997">
+<ul class="toc-indentation"><li><a
href="#PageAndComponentClassesFAQ-What'sthedifferencebetweenapageandacomponent?">What's
the difference between a page and a component?</a></li><li><a
href="#PageAndComponentClassesFAQ-HowdoIstoremypageclassesinadifferentpackage?">How
do I store my page classes in a different package?</a></li><li><a
href="#PageAndComponentClassesFAQ-Whydomyinstancevariableshavetobeprivate?">Why
do my instance variables have to be private?</a></li><li><a
href="#PageAndComponentClassesFAQ-Whydon'tmyinformalparametersshowupintherenderedmarkup?">Why
don't my informal parameters show up in the rendered markup?</a></li><li><a
href="#PageAndComponentClassesFAQ-WhydoIgetjava.lang.LinkageErrorwhenIinvokepublicmethodsofmypageclasses?">Why
do I get java.lang.LinkageError when I invoke public methods of my page
classes?</a></li><li><a
href="#PageAndComponentClassesFAQ-Whichisbetter,usingmagicmethodnames(i.e.,beginRender())orannotations(i.e.BeginRender)?">Which
is better,
using magic method names (i.e., beginRender()) or annotations (i.e.
BeginRender)?</a></li><li><a
href="#PageAndComponentClassesFAQ-WhydoIhavetoinjectapage?Whycan'tIjustcreateoneusingnew?">Why
do I have to inject a page? Why can't I just create one using
new?</a></li></ul>
+</div><h2
id="PageAndComponentClassesFAQ-What'sthedifferencebetweenapageandacomponent?">What's
the difference between a page and a component?</h2><p>There's very little
difference between the two. Pages classes must be in the
<em>root-package</em>.<code>pages</code> package; components must be in the
<em>root-package</em>.<code>components</code>. Pages may provide event handlers
for certain page-specific events (such as activate and passivate). Components
may have parameters.</p><p>Other than that, they are more equal than they are
different. They may have templates or may render themselves in code (pages
usually have a template, components are more likely to render only in
code).</p><p>The major difference is that Tapestry page templates may be stored
in the web context directory, as if they were static files (they can't be
accessed from the client however; a specific rule prevents access to files with
the <code>.tml</code> extension).</p><div class="confluence-information-macro co
nfluence-information-macro-warning"><span class="aui-icon aui-icon-small
aui-iconfont-error confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>It is possible that this feature
may be removed in a later release. It is preferred that page templates be
stored on the classpath, like component templates.</p></div></div><h2
id="PageAndComponentClassesFAQ-HowdoIstoremypageclassesinadifferentpackage?">How
do I store my page classes in a different package?</h2><p>Tapestry is very
rigid here; you can't. Page classes must go in
<em>root-package</em>.<code>pages</code>, component classes in
<em>root-package</em>.<code>components</code>, etc.</p><p>You are allowed to
create sub-packages, to help organize your code better and more logically. For
example, you might have
<em>root-package</em>.<code>pages.account.ViewAccount</code>, which would have
the page name "account/viewaccount". (<span>Tapestry would also create an alias
"account/view", by stripping of
f the redundant "account" suffix. Either name is equally valid in your code,
and Tapestry will use the shorter name, "account/view" in
URLs.)</span></p><p>In addition, it is possible to define additional root
packages for the application:</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 static void
contributeComponentClassResolver(Configuration<LibraryMapping>
configuration) {
configuration.add(new LibraryMapping("", "com.example.app.tasks"));
configuration.add(new LibraryMapping("", "com.example.app.chat"));
}
</pre>
-</div></div><p>LibraryMappings are used to resolve a library prefix to one or
more package names. The empty string represents the application itself; the
above example adds two additional root packages; you might see additional pages
under <code>com.example.app.tasks.pages</code>, for example.</p><div
class="confluence-information-macro confluence-information-macro-warning"><span
class="aui-icon aui-icon-small aui-iconfont-error
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Tapestry doesn't check for name
collisions, and the order the packages are searched for pages and components is
not defined. In general, if you can get by with a single root package for your
application, that is better.</p></div></div><h3
id="PageAndComponentClassesFAQ-Whydomyinstancevariableshavetobeprivate?">Why do
my instance variables have to be private?</h3><p><em>In Tapestry 5.3.1 and
earlier all instance variables must be private. Starting in version 5.3.2 inst
ance variables can also be protected or package private (that is, not public),
or they can even be public if <code>final</code> or annotated with the
deprecated @Retain.</em></p><p>Tapestry does a large amount of transformation
to your simple POJO classes as it loads them into memory. In many cases, it
must locate every read or write of an instance variable and change its
behavior; for example, reading a field that is a component parameter will cause
a property of the containing page or component to be read.</p><p>Restricting
the scope of fields allows Tapestry to do the necessary processing one class at
a time, as needed, at runtime. More complex Aspect Orient Programming systems
such as AspectJ can perform similar transformations (and much more complex
ones), but they require a dedicated build step (or the introduction of a JVM
agent).</p><h3
id="PageAndComponentClassesFAQ-Whydon'tmyinformalparametersshowupintherenderedmarkup?">Why
don't my informal parameters show up in the rende
red markup?</h3><p>Getting informal parameters to work is in two steps. First,
you must make a call to the
<code>ComponentResources.renderInformalParameters()</code> method, but just as
importantly, you must tell Tapestry that you want the component to support
informal parameters, using the <code>SupportsInformalParameters</code>
annotation. Here's a hypothetical component that displays an image based on the
value of a <code>Image</code> object (presumably, a database entity):</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+</div></div><p>LibraryMappings are used to resolve a library prefix to one or
more package names. The empty string represents the application itself; the
above example adds two additional root packages; you might see additional pages
under <code>com.example.app.tasks.pages</code>, for example.</p><div
class="confluence-information-macro confluence-information-macro-warning"><span
class="aui-icon aui-icon-small aui-iconfont-error
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Tapestry doesn't check for name
collisions, and the order the packages are searched for pages and components is
not defined. In general, if you can get by with a single root package for your
application, that is better.</p></div></div><h2
id="PageAndComponentClassesFAQ-Whydomyinstancevariableshavetobeprivate?">Why do
my instance variables have to be private?</h2><p><em>In Tapestry 5.3.1 and
earlier all instance variables must be private. Starting in version 5.3.2 inst
ance variables can also be protected or package private (that is, not public),
or they can even be public if <code>final</code> or annotated with the
deprecated @Retain.</em></p><p>Tapestry does a large amount of transformation
to your simple POJO classes as it loads them into memory. In many cases, it
must locate every read or write of an instance variable and change its
behavior; for example, reading a field that is a component parameter will cause
a property of the containing page or component to be read.</p><p>Restricting
the scope of fields allows Tapestry to do the necessary processing one class at
a time, as needed, at runtime. More complex Aspect Orient Programming systems
such as AspectJ can perform similar transformations (and much more complex
ones), but they require a dedicated build step (or the introduction of a JVM
agent).</p><h2
id="PageAndComponentClassesFAQ-Whydon'tmyinformalparametersshowupintherenderedmarkup?">Why
don't my informal parameters show up in the rende
red markup?</h2><p>Getting informal parameters to work is in two steps. First,
you must make a call to the
<code>ComponentResources.renderInformalParameters()</code> method, but just as
importantly, you must tell Tapestry that you want the component to support
informal parameters, using the <code>SupportsInformalParameters</code>
annotation. Here's a hypothetical component that displays an image based on the
value of a <code>Image</code> object (presumably, a database entity):</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;">@SupportsInformalParameters
public class DBImage
{
@@ -105,29 +112,29 @@ public class DBImage
}
}
</pre>
-</div></div><h3
id="PageAndComponentClassesFAQ-WhydoIgetjava.lang.LinkageErrorwhenIinvokepublicmethodsofmypageclasses?">Why
do I get java.lang.LinkageError when I invoke public methods of my page
classes?</h3><p>In Tapestry, there are always <em>two</em> versions of page (or
component) classes. The first version is the version loaded by standard class
loader: the simple POJO version that you wrote.</p><p>The second version is
much more complicated; it's the transformed version of your code, with lots of
extra hooks and changes to allow the class to operate inside Tapestry. This
includes implementing new interfaces and methods, adding new constructors, and
changing access to existing fields and methods.</p><p>Although these two
classes have the same fully qualified class name, they are distinct classes
because they are loaded by different class loaders.</p><p>
+</div></div><h2
id="PageAndComponentClassesFAQ-WhydoIgetjava.lang.LinkageErrorwhenIinvokepublicmethodsofmypageclasses?">Why
do I get java.lang.LinkageError when I invoke public methods of my page
classes?</h2><p>In Tapestry, there are always <em>two</em> versions of page (or
component) classes. The first version is the version loaded by standard class
loader: the simple POJO version that you wrote.</p><p>The second version is
much more complicated; it's the transformed version of your code, with lots of
extra hooks and changes to allow the class to operate inside Tapestry. This
includes implementing new interfaces and methods, adding new constructors, and
changing access to existing fields and methods.</p><p>Although these two
classes have the same fully qualified class name, they are distinct classes
because they are loaded by different class loaders.</p><p>
-<span class="gliffy-container" id="gliffy-container-23527573-206"
data-fullwidth="750" data-ceoid="23335008"
data-edit="${diagramEditLink.getLinkUrl()}"
data-full="${diagramZoomLink.getLinkUrl()}" data-filename="Class Loaders">
+<span class="gliffy-container" id="gliffy-container-23527573-4104"
data-fullwidth="750" data-ceoid="23335008"
data-edit="${diagramEditLink.getLinkUrl()}"
data-full="${diagramZoomLink.getLinkUrl()}" data-filename="Class Loaders">
- <map id="gliffy-map-23527573-6113" name="gliffy-map-23527573-6113"></map>
+ <map id="gliffy-map-23527573-3751" name="gliffy-map-23527573-3751"></map>
- <img class="gliffy-image" id="gliffy-image-23527573-206" width="750"
height="425" data-full-width="750" data-full-height="425"
src="https://cwiki.apache.org/confluence/download/attachments/23335008/Class%20Loaders.png?version=4&modificationDate=1283534469000&api=v2"
alt="Class Loaders" usemap="#gliffy-map-23527573-6113">
+ <img class="gliffy-image" id="gliffy-image-23527573-4104" width="750"
height="425" data-full-width="750" data-full-height="425"
src="https://cwiki.apache.org/confluence/download/attachments/23335008/Class%20Loaders.png?version=4&modificationDate=1283534469000&api=v2"
alt="Class Loaders" usemap="#gliffy-map-23527573-3751">
- <map class="gliffy-dynamic" id="gliffy-dynamic-map-23527573-206"
name="gliffy-dynamic-map-23527573-206"></map>
+ <map class="gliffy-dynamic" id="gliffy-dynamic-map-23527573-4104"
name="gliffy-dynamic-map-23527573-4104"></map>
</span>
-</p><p>In a Tapestry application, most application classes are loaded from the
middle class loader. Additional class loaders are used<br clear="none"> to
support live service reloading, and live component reloading (along with
component class transformation).</p><p>When a page or component is passed as a
parameter to a service, a failure occurs (how it is reported varies in
different JDK releases) because of the class mismatch.</p><p>The solution is to
define an interface with the methods that the service will invoke on the page
or component instance. The service will expect an object implementing the
interface (and doesn't care what class loader loaded the implementing
class).</p><p>Just be sure to put the interface class in a non-controlled
package, such as your application's <em>root-package</em> (and
<strong>not</strong> <em>root-package</em>.<code>pages</code>).</p><h3
id="PageAndComponentClassesFAQ-Whichisbetter,usingmagicmethodnames(i.e.,beginRender())orannotations(i.e.BeginR
ender)?">Which is better, using magic method names (i.e.,
<code>beginRender()</code>) or annotations (i.e.
<code>BeginRender</code>)?</h3><p>There is no single best way; this is where
your taste may vary. Historically, the annotations came first, and the method
naming conventions came later.</p><p>The advantage of using the method naming
conventions is that the method names are more concise, which fewer characters
to type, and fewer classes to import.</p><p>The main disadvantage of the method
naming conventions is that the method names are not meaningful.
<code>onSuccessFromLoginForm()</code> is a less meaningful name than
<code>storeUserCredentialsAndReturnToProductsPage()</code>, for
example.</p><p>The second disadvantage is you are more susceptible to
off-by-a-character errors. For example, <code>onSucessFromLoginForm()</code>
will <em>never</em> be called because the event name is misspelled; this would
not happen using the annotation approach:</p><div class="code panel pdl" sty
le="border-width: 1px;"><div class="codeContent panelContent pdl">
+</p><p>In a Tapestry application, most application classes are loaded from the
middle class loader. Additional class loaders are used<br clear="none"> to
support live service reloading, and live component reloading (along with
component class transformation).</p><p>When a page or component is passed as a
parameter to a service, a failure occurs (how it is reported varies in
different JDK releases) because of the class mismatch.</p><p>The solution is to
define an interface with the methods that the service will invoke on the page
or component instance. The service will expect an object implementing the
interface (and doesn't care what class loader loaded the implementing
class).</p><p>Just be sure to put the interface class in a non-controlled
package, such as your application's <em>root-package</em> (and
<strong>not</strong> <em>root-package</em>.<code>pages</code>).</p><h2
id="PageAndComponentClassesFAQ-Whichisbetter,usingmagicmethodnames(i.e.,beginRender())orannotations(i.e.BeginR
ender)?">Which is better, using magic method names (i.e.,
<code>beginRender()</code>) or annotations (i.e.
<code>BeginRender</code>)?</h2><p>There is no single best way; this is where
your taste may vary. Historically, the annotations came first, and the method
naming conventions came later.</p><p>The advantage of using the method naming
conventions is that the method names are more concise, which fewer characters
to type, and fewer classes to import.</p><p>The main disadvantage of the method
naming conventions is that the method names are not meaningful.
<code>onSuccessFromLoginForm()</code> is a less meaningful name than
<code>storeUserCredentialsAndReturnToProductsPage()</code>, for
example.</p><p>The second disadvantage is you are more susceptible to
off-by-a-character errors. For example, <code>onSucessFromLoginForm()</code>
will <em>never</em> be called because the event name is misspelled; this would
not happen using the annotation approach:</p><div class="code panel pdl" sty
le="border-width: 1px;"><div class="codeContent panelContent pdl">
<pre class="brush: java; gutter: true; theme: Default"
style="font-size:12px;"> @OnEvent(value=EventConstants.SUCCESS,
component="loginForm")
Object storeUserCredentialsAndReturnToProductsPage()
{
. . .
}
</pre>
-</div></div><p>The compiler will catch a misspelling of the constant
<code>SUCCESS</code>. Likewise, local constants can be defined for key
components, such as "loginForm".</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>Ultimately, it's developer choice.
HLS prefers the method naming conventions in nearly all cases, especially
prototypes and demos, but can see that in some projects and some teams, an
annotation-only approach is best.</p></div></div><h3
id="PageAndComponentClassesFAQ-WhydoIhavetoinjectapage?Whycan'tIjustcreateoneusingnew?">Why
do I have to inject a page? Why can't I just create one using
new?</h3><p>Tapestry tranforms your class at runtime. It tends to build a large
constructor for the class instance. Further, an instance of the class is
useless by itself, it must be wired together wi
th its template and its sub-components.</p><p>On top of that, Tapestry keeps
just once instance of each page in memory (since 5.2). It reworks the bytecode
of the components so that a single instance can be shared across multiple
request handling
threads.____</p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p></p><div
class="display-footnotes"
data-footnotestodisplay="${footnotesToDisplay}"></div>
+</div></div><p>The compiler will catch a misspelling of the constant
<code>SUCCESS</code>. Likewise, local constants can be defined for key
components, such as "loginForm".</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>Ultimately, it's developer choice.
HLS prefers the method naming conventions in nearly all cases, especially
prototypes and demos, but can see that in some projects and some teams, an
annotation-only approach is best.</p></div></div><h2
id="PageAndComponentClassesFAQ-WhydoIhavetoinjectapage?Whycan'tIjustcreateoneusingnew?">Why
do I have to inject a page? Why can't I just create one using
new?</h2><p>Tapestry tranforms your class at runtime. It tends to build a large
constructor for the class instance. Further, an instance of the class is
useless by itself, it must be wired together wi
th its template and its sub-components.</p><p>On top of that, Tapestry keeps
just once instance of each page in memory (since 5.2). It reworks the bytecode
of the components so that a single instance can be shared across multiple
request handling
threads.____</p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p></p><div
class="display-footnotes"
data-footnotestodisplay="${footnotesToDisplay}"></div>
<p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p></div>
</div>
Modified: websites/production/tapestry/content/templating-and-markup-faq.html
==============================================================================
--- websites/production/tapestry/content/templating-and-markup-faq.html
(original)
+++ websites/production/tapestry/content/templating-and-markup-faq.html Mon Feb
19 18:20:23 2018
@@ -77,11 +77,18 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><h2
id="TemplatingandMarkupFAQ-TemplatingandMarkup">Templating and
Markup</h2><p>Main Article: <a
href="templating-and-markup-faq.html">Templating and Markup FAQ</a></p><h3
id="TemplatingandMarkupFAQ-WhydoIgetaSAXParseExceptionwhenIuseanHTMLentity,suchas&nbsp;inmytemplate?">Why
do I get a SAXParseException when I use an HTML entity, such as
<code>&nbsp;</code> in my template?</h3><p>Tapestry uses a standard SAX
parser to read your templates. This means that your templates must be <em>well
formed</em>: open and close tags must balance, attribute values must be quoted,
and entities must be declared. The easiest way to accomplish this is to add a
DOCTYPE to your the top of your template:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+ <div id="ConfluenceContent"><h1
id="TemplatingandMarkupFAQ-TemplatingandMarkup">Templating and
Markup</h1><p>Main Article: <a href="component-templates.html">Component
Templates</a></p><h2
id="TemplatingandMarkupFAQ-Contents">Contents</h2><p><style
type="text/css">/*<![CDATA[*/
+div.rbtoc1519064396313 {padding: 0px;}
+div.rbtoc1519064396313 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1519064396313 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1519064396313">
+<ul class="toc-indentation"><li><a
href="#TemplatingandMarkupFAQ-WhydoIgetaSAXParseExceptionwhenIuseanHTMLentity,suchas&nbsp;inmytemplate?">Why
do I get a SAXParseException when I use an HTML entity, such as &nbsp; in
my template?</a></li><li><a
href="#TemplatingandMarkupFAQ-Whydosomeimagesinmypageshowupasbrokenlinks?">Why
do some images in my page show up as broken links?</a></li><li><a
href="#TemplatingandMarkupFAQ-What'sthedifferencebetweenidandt:id?">What's the
difference between id and t:id?</a></li><li><a
href="#TemplatingandMarkupFAQ-WhydomyimagesandstylesheetsendupwithaweirdURLslike/assets/meta/zeea17aee26bc0cae/layout/layout.css?">Why
do my images and stylesheets end up with a weird URLs like
/assets/meta/zeea17aee26bc0cae/layout/layout.css?</a></li><li><a
href="#TemplatingandMarkupFAQ-HowdoIaddaCSSclasstoaTapestrycomponent?">How do I
add a CSS class to a Tapestry component?</a></li></ul>
+</div><h2
id="TemplatingandMarkupFAQ-WhydoIgetaSAXParseExceptionwhenIuseanHTMLentity,suchas&nbsp;inmytemplate?">Why
do I get a SAXParseException when I use an HTML entity, such as
<code>&nbsp;</code> in my template?</h2><p>Tapestry uses a standard SAX
parser to read your templates. This means that your templates must be <em>well
formed</em>: open and close tags must balance, attribute values must be quoted,
and entities must be declared. The easiest way to accomplish this is to add a
DOCTYPE to your the top of your template:</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;"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
</pre>
-</div></div><p>Part of the DOCTYPE is the declaration of entities such as
<code>&nbsp;</code>.</p><p>Alternately, you can simply use the numeric
version: <code>&#160</code>; This is the exact same character and will
render identically in the browser.</p><p>Starting in release 5.3, Tapestry
introduces an XHTML doctype when no doctype is present; this means that common
HTML entities will work correctly.</p><h3
id="TemplatingandMarkupFAQ-Whydosomeimagesinmypageshowupasbrokenlinks?">Why do
some images in my page show up as broken links?</h3><p>You have to be careful
when using relative URLs inside page templates; the base URL may not always be
what you expect. For example, inside your <code>ViewUser.tml</code> file, you
may have:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+</div></div><p>Part of the DOCTYPE is the declaration of entities such as
<code>&nbsp;</code>.</p><p>Alternately, you can simply use the numeric
version: <code>&#160</code>; This is the exact same character and will
render identically in the browser.</p><p>Starting in release 5.3, Tapestry
introduces an XHTML doctype when no doctype is present; this means that common
HTML entities will work correctly.</p><h2
id="TemplatingandMarkupFAQ-Whydosomeimagesinmypageshowupasbrokenlinks?">Why do
some images in my page show up as broken links?</h2><p>You have to be careful
when using relative URLs inside page templates; the base URL may not always be
what you expect. For example, inside your <code>ViewUser.tml</code> file, you
may have:</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;"> <img class="icon"
src="icons/admin.png"/>${user.name} has Administrative access
</pre>
</div></div><p>This makes sense; ViewUser.tml is in the web context, as is the
icons folder. The default URL for this page will be /viewuser (assuming that
ViewUser class is in the  <em>root-package</em>.pages
package).</p><p>However, the ViewUser page might use a page activation context
to identify which user is to be displayed:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
@@ -99,7 +106,7 @@
</div></div><p>But this has its own problems; the page activation context may
vary in length at different times, or the template in question may be a
component used across many different pages, making it difficult to predict what
the correct relative URL would be.</p><p>The <em>best</em> solution for this
situation, one that will be sure to work in all pages and all components, is to
make use of the <code>context:</code> binding prefix:</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;"> <img class="icon"
src="${context:icons/admin.png}"/>${user.name} has Administrative access
</pre>
-</div></div><p>The src attribute of the <img> tag will now be bound to a
dynamically computed value: the location of the image file relative to the web
application context. This is especially important for components that may be
used on different pages.</p><h3
id="TemplatingandMarkupFAQ-What'sthedifferencebetweenidandt:id?">What's the
difference between <code>id</code> and <code>t:id</code>?</h3><p>You might
occasionally see something like the following in a template:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+</div></div><p>The src attribute of the <img> tag will now be bound to a
dynamically computed value: the location of the image file relative to the web
application context. This is especially important for components that may be
used on different pages.</p><h2
id="TemplatingandMarkupFAQ-What'sthedifferencebetweenidandt:id?">What's the
difference between <code>id</code> and <code>t:id</code>?</h2><p>You might
occasionally see something like the following in a template:</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="status" t:id="statusZone">
</pre>
</div></div><p>Why two ids? Why are they different?</p><p>The
<code>t:id</code> attribute is the Tapestry component id. This id is unique
within its immediate container. This is the id you might use to inject the
component into your page class:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
@@ -109,7 +116,7 @@
</div></div><p>The other id is the client id, a unique id for the rendered
element within the client-side DOM. JavaScript that needs to access the element
uses this id. For example:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
<pre class="brush: text; gutter: false; theme: Default"
style="font-size:12px;"> $('status').hide();
</pre>
-</div></div><p>In many components, the <code>id</code> attribute is an
informal parameter; a value from the template that is blindly echoed into the
output document. In other cases, the component itself has an <code>id</code>
attribute. Often, in the latter case, the Tapestry component id is the
<em>default</em> value for the client id.</p><h3
id="TemplatingandMarkupFAQ-WhydomyimagesandstylesheetsendupwithaweirdURLslike/assets/meta/zeea17aee26bc0cae/layout/layout.css?">Why
do my images and stylesheets end up with a weird URLs like
<code>/assets/meta/zeea17aee26bc0cae/layout/layout.css</code>?</h3><p>Tapestry
doesn't rely on the servlet container to serve up your static assets (images,
stylesheets, flash movies, etc.). Instead, Tapestry processes the requests
itself, streaming assets to the browser.</p><p>Asset content will be GZIP
compressed (if the client supports compression, and the content is
compressible). In addition, Tapestry will set a far-future expires header on
the conten
t. This means that the browser will not ask for the file again, greatly
reducing network traffic.</p><p>The weird hex string is
a <em>fingerprint</em>; it is a hash code computed from the actual content
of the asset. If the asset ever changes, it will have a new fingerprint, and so
will be a new path and a new (immutable) resource. This approach, combined with
a far-future expires header also provided by Tapestry, ensures that clients
aggressively cache assets as they navigate your site, or even between
visits.</p><p><span style="color: rgb(83,145,38);">How do I add a CSS class to
a Tapestry component?</span></p><p>As they say, "just do it". The majority of
Tapestry components support <em>informal parameters</em>, meaning that any
extra attributes in the element (in the template) will be rendered out as
additional attributes. So, you can apply a CSS class or style quite
easily:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+</div></div><p>In many components, the <code>id</code> attribute is an
informal parameter; a value from the template that is blindly echoed into the
output document. In other cases, the component itself has an <code>id</code>
attribute. Often, in the latter case, the Tapestry component id is the
<em>default</em> value for the client id.</p><h2
id="TemplatingandMarkupFAQ-WhydomyimagesandstylesheetsendupwithaweirdURLslike/assets/meta/zeea17aee26bc0cae/layout/layout.css?">Why
do my images and stylesheets end up with a weird URLs like
<code>/assets/meta/zeea17aee26bc0cae/layout/layout.css</code>?</h2><p>Tapestry
doesn't rely on the servlet container to serve up your static assets (images,
stylesheets, flash movies, etc.). Instead, Tapestry processes the requests
itself, streaming assets to the browser.</p><p>Asset content will be GZIP
compressed (if the client supports compression, and the content is
compressible). In addition, Tapestry will set a far-future expires header on
the conten
t. This means that the browser will not ask for the file again, greatly
reducing network traffic.</p><p>The weird hex string is
a <em>fingerprint</em>; it is a hash code computed from the actual content
of the asset. If the asset ever changes, it will have a new fingerprint, and so
will be a new path and a new (immutable) resource. This approach, combined with
a far-future expires header also provided by Tapestry, ensures that clients
aggressively cache assets as they navigate your site, or even between
visits.</p><h2
id="TemplatingandMarkupFAQ-HowdoIaddaCSSclasstoaTapestrycomponent?"><span
style="color: rgb(83,145,38);">How do I add a CSS class to a Tapestry
component?</span></h2><p>As they say, "just do it". The majority of Tapestry
components support <em>informal parameters</em>, meaning that any extra
attributes in the element (in the template) will be rendered out as additional
attributes. So, you can apply a CSS class or style quite easily:</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="username" class="big-green"/>
</pre>
</div></div><p>You can even use template expansions inside the attribute
value:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">