Modified: websites/production/tapestry/content/component-rendering.html
==============================================================================
--- websites/production/tapestry/content/component-rendering.html (original)
+++ websites/production/tapestry/content/component-rendering.html Wed Sep 20
12:29:16 2017
@@ -27,6 +27,16 @@
</title>
<link type="text/css" rel="stylesheet" href="/resources/space.css" />
+ <link href='/resources/highlighter/styles/shCoreCXF.css'
rel='stylesheet' type='text/css' />
+ <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet'
type='text/css' />
+ <script src='/resources/highlighter/scripts/shCore.js'
type='text/javascript'></script>
+ <script src='/resources/highlighter/scripts/shBrushJava.js'
type='text/javascript'></script>
+ <script src='/resources/highlighter/scripts/shBrushXml.js'
type='text/javascript'></script>
+ <script src='/resources/highlighter/scripts/shBrushPlain.js'
type='text/javascript'></script>
+ <script>
+ SyntaxHighlighter.defaults['toolbar'] = false;
+ SyntaxHighlighter.all();
+ </script>
<link href="/styles/style.css" rel="stylesheet" type="text/css"/>
@@ -67,7 +77,86 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><p><strong>Rendering of
components</strong> in Tapestry 5 is based on a <em>state machine</em> and a
<em>queue</em> (instead of the tail recursion used in Tapestry 4). This breaks
the rendering process up into tiny pieces that can easily be implemented or
overridden. Don't worry, in practice, writing components requires a
breathtakingly small amount of code.</p><parameter
ac:name="style">float:right</parameter><parameter ac:name="title">Related
Articles</parameter><parameter
ac:name="class">aui-label</parameter><rich-text-body><parameter
ac:name="showLabels">false</parameter><parameter
ac:name="showSpace">false</parameter><parameter ac:name="title">Related
Articles</parameter><parameter ac:name="cql">label in
("request-processing","rendering") and space =
currentSpace()</parameter></rich-text-body><h2
id="ComponentRendering-RenderingPhases">Rendering Phases</h2><p>The rendering
of each component is divided into a number of phases, illustra
ted below.</p><p><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image"
src="component-rendering.data/tapestry_render_phases.png"></span><br
clear="none"> Each of the orange phases (SetupRender, BeginRender,
BeforeRenderBody, etc.) corresponds to an annotation you may place on one or
more methods of your class. The annotation directs Tapestry to invoke your
method as part of that phase.</p><p>Methods marked with these annotations are
called <strong>render phase methods</strong>.</p><p>Your methods may be void,
or return a boolean value. Returning a value can force phases to be skipped, or
even be re-visited. In the diagram, solid lines show the normal processing
path. Dashed lines are alternate flows that are triggered when your render
phase methods return false instead of true (or void).</p><p>Render phase
methods may take no parameters, or may take a parameter of type <a
href="dom.html">MarkupWriter</a>. The methods can have any visibility you like
... typically, package private is used, as this visibility makes it possible
to unit test your code (from within the same Java package) without making the
methods part of the component's <em>public</em> API.</p><p>All Render phase
methods are <em>optional</em>; a default behavior is associated with each
phase.</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th
colspan="1" rowspan="1" class="confluenceTh"><p>Annotation</p></th><th
colspan="1" rowspan="1" class="confluenceTh"><p>Method Name</p></th><th
colspan="1" rowspan="1" class="confluenceTh"><p>When
Called</p></th></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SetupRender.html">@SetupRender</a></strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>setupRender()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>When initial setup actions, if
any, are needed
</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeginRender">@BeginRender</a></strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>beginRender()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>When Tapestry is ready for the
component's start tag, if any, to be rendered</p></td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderTemplate">@BeforeRenderTemplate</a></p></td><td
colspan="1" rowspan="1"
class="confluenceTd"><p>beforeRenderTemplate()</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Before Tapestry renders the component's
template, if any</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><a class="external-link"
href="http://tapestry.apache.org/current/
apidocs/org/apache/tapestry5/annotations/BeforeRenderBody">@BeforeRenderBody</a></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>beforeRenderBody()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Before Tapestry renders the
body of the component, if any</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRenderBody">@AfterRenderBody</a></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>afterRenderBody()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>After Tapestry renders the body
of the component, if any, but before the rest of the component's template is
rendered</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRenderTemplate">@AfterRenderTemplate</a></p></td><td
colspan="1" r
owspan="1" class="confluenceTd"><p>afterRenderTemplate()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>After Tapestry finishes
rendering the component's template, if any</p></td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRender">@AfterRender</a></strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>afterRender()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>After Tapestry has finished
rendering both the template and body of the component</p></td></tr><tr><td
colspan="1" rowspan="1" class="confluenceTd"><p><strong><a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/CleanupRender">@CleanupRender</a></strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>cleanupRender()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>When fina
l cleanup actions, if any, are
needed</p></td></tr></tbody></table></div><p>The large number of phases
reflects the need for precise control of components from <a
href="component-mixins.html">component mixins</a>. Several of the phases exist
almost exclusively for mixins.</p><p>Generally, your code will use the
SetupRender, BeginRender, AfterRender and CleanupRender phases ... often just
one or two of those.</p><h2 id="ComponentRendering-AnExample">An
Example</h2><p>Here's the source for a looping component that counts up or down
between two values, renders its body a number of times, and stores the current
index value in a parameter:</p><parameter
ac:name="">java</parameter><plain-text-body>package org.example.app.components;
+ <div id="ConfluenceContent"><p><strong>Rendering of
components</strong> in Tapestry 5 is based on a <em>state machine</em> and a
<em>queue</em> (instead of the tail recursion used in Tapestry 4). This breaks
the rendering process up into tiny pieces that can easily be implemented or
overridden. Don't worry, in practice, writing components requires a
breathtakingly small amount of code.</p><div class="aui-label"
style="float:right" title="Related Articles">
+
+
+
+
+
+
+
+
+<h3>Related Articles</h3>
+
+<ul class="content-by-label"><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="content-type-and-markup.html">Content Type
and Markup</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="page-navigation.html">Page Navigation</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="page-life-cycle.html">Page Life Cycle</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="component-rendering.html">Component
Rendering</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="component-events.html">Component Events</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="component-events-faq.html">Component Events
FAQ</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="request-processing.html">Request
Processing</a>
+
+
+ </div>
+ </li></ul>
+</div>
+
+
+<h2 id="ComponentRendering-RenderingPhases">Rendering Phases</h2><p>The
rendering of each component is divided into a number of phases, illustrated
below.</p><p><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image"
src="component-rendering.data/tapestry_render_phases.png"></span><br
clear="none"> Each of the orange phases (SetupRender, BeginRender,
BeforeRenderBody, etc.) corresponds to an annotation you may place on one or
more methods of your class. The annotation directs Tapestry to invoke your
method as part of that phase.</p><p>Methods marked with these annotations are
called <strong>render phase methods</strong>.</p><p>Your methods may be void,
or return a boolean value. Returning a value can force phases to be skipped, or
even be re-visited. In the diagram, solid lines show the normal processing
path. Dashed lines are alternate flows that are triggered when your render
phase methods return false instead of true (or void).</p><p>Render phase met
hods may take no parameters, or may take a parameter of type <a
href="dom.html">MarkupWriter</a>. The methods can have any visibility you like
... typically, package private is used, as this visibility makes it possible to
unit test your code (from within the same Java package) without making the
methods part of the component's <em>public</em> API.</p><p>All Render phase
methods are <em>optional</em>; a default behavior is associated with each
phase.</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><th
colspan="1" rowspan="1" class="confluenceTh"><p>Annotation</p></th><th
colspan="1" rowspan="1" class="confluenceTh"><p>Method Name</p></th><th
colspan="1" rowspan="1" class="confluenceTh"><p>When
Called</p></th></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SetupRender.html">@SetupRender</a></strong></p></td><td
colspan="1" rowspan="1"
class="confluenceTd"><p>setupRender()</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>When initial setup actions, if any, are
needed</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeginRender">@BeginRender</a></strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>beginRender()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>When Tapestry is ready for the
component's start tag, if any, to be rendered</p></td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderTemplate">@BeforeRenderTemplate</a></p></td><td
colspan="1" rowspan="1"
class="confluenceTd"><p>beforeRenderTemplate()</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Before Tapestry renders the component's
template,
if any</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderBody">@BeforeRenderBody</a></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>beforeRenderBody()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Before Tapestry renders the
body of the component, if any</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRenderBody">@AfterRenderBody</a></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>afterRenderBody()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>After Tapestry renders the body
of the component, if any, but before the rest of the component's template is
rendered</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><a class="external-link" href="htt
p://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRenderTemplate">@AfterRenderTemplate</a></p></td><td
colspan="1" rowspan="1"
class="confluenceTd"><p>afterRenderTemplate()</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>After Tapestry finishes rendering the
component's template, if any</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong><a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRender">@AfterRender</a></strong></p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>afterRender()</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>After Tapestry has finished
rendering both the template and body of the component</p></td></tr><tr><td
colspan="1" rowspan="1" class="confluenceTd"><p><strong><a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/CleanupRender">@CleanupRender</a></strong></
p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>cleanupRender()</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>When final cleanup actions, if any, are
needed</p></td></tr></tbody></table></div><p>The large number of phases
reflects the need for precise control of components from <a
href="component-mixins.html">component mixins</a>. Several of the phases exist
almost exclusively for mixins.</p><p>Generally, your code will use the
SetupRender, BeginRender, AfterRender and CleanupRender phases ... often just
one or two of those.</p><h2 id="ComponentRendering-AnExample">An
Example</h2><p>Here's the source for a looping component that counts up or down
between two values, renders its body a number of times, and stores the current
index value in a parameter:</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;">package org.example.app.components;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.AfterRender;
@@ -121,11 +210,11 @@ public class Count
return true;
}
}
-</plain-text-body><p>Returning false from next() causes Tapestry to re-run the
BeginRender phase, and from there, re-render the component's body (this
component does not have a template). Returning true transitions to the
CleanupRender phase.</p><p>Notice how Tapestry adapts to your methods, as
marked with the annotations. It also adapts in terms of parameters; the two
annotated methods here did not perform any output, so they did not need a
MarkupWriter.</p><p>What's really mind blowing is that the template and body of
a component will often contain ... more components! That means that many
different components will be in different phases of their own state
machine.</p><h2 id="ComponentRendering-RenderPhasesinDetail">Render Phases in
Detail</h2><p><plain-text-body>{float:right|background=#eee|width=50%}
-{note}
-The SetupRender phase, like all render phases, occurs once for each rendering
of the component. If the component is inside a looping component
([Loop|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Loop.html],
[Grid|http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Grid.html],
etc.), then the SetupRender method will be called once for _each_ iteration of
the loop.
-{note}
-{float}</plain-text-body></p><h3
id="ComponentRendering-SetupRender">SetupRender</h3><p>The SetupRender phase
(see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SetupRender.html">SetupRender</a>)
is where you can perform any one-time per-render setup for your component.
This is a good place to read component parameters and use them to set temporary
instance variables.</p><h3
id="ComponentRendering-BeginRender">BeginRender</h3><p>The BeginRender phase
(see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeginRender.html">BeginRender</a>)
occurs at the start of the rendering of the component. For components that
render a tag, the start tag should be rendered here (the close tag should be
rendered inside the AfterRender phase). The component can also prevent the
template and/or body from being rendered by returning false.</p><p>Components
may or may not have a tem
plate. If a component has a template, and the template includes a <body>
element, then the BeforeRenderBody phase will be triggered (giving the
component the option of rendering its body or not).</p><p>If a component does
not have a <body> element in its template, then the BeforeRenderBody
phase is not triggered.</p><p>If a component does not have a template, but does
have a body, the BeforeRenderBody phase is still triggered.</p><p>If no methods
are annotated with BeginRender, then no special output occurs during this
phase, but the template (if present) or body (if no template is present, but
the component has a body) will be rendered.</p><h3
id="ComponentRendering-BeforeRenderTemplate">BeforeRenderTemplate</h3><p>The
BeforeRenderTemplate phase (see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderTemplate.html">BeforeRenderTemplate</a>)
exists to allow a component to decorate its template (creatin
g markup around the template generated markup), or to allow a component to
skip its template.</p><h3
id="ComponentRendering-BeforeRenderBody">BeforeRenderBody</h3><p>The
BeforeRenderBody phase (see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderBody.html">BeforeRenderBody</a>)
is associated with a component's body (the portion of its container's template
that the component occupies). The BeforeRenderBody phase allows the component
the ability to skip the body, while still rendering the rest of the component's
template (if any).</p><p>If no methods are annotated with BeforeRenderBody,
then the body will be rendered by default. Again, this occurs when the
<body> element of the component's template is reached, or automatically
if the component has no template (but the component does have a body).</p><h3
id="ComponentRendering-AfterRenderBody">AfterRenderBody</h3><p>The
AfterRenderBody phase (see @<a class=
"external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRenderBody.html">AfterRenderBody</a>)
is executed after the body is rendered; this only occurs for components with a
body.</p><h3 id="ComponentRendering-AfterRender">AfterRender</h3><p>The
AfterRender phase (see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRender.html">AfterRender</a>)
complements BeginRender, and is often used to render the close tag that
matches the start tag rendered in the BeginRender phase. In any case, the
AfterRender phase can continue on to CleanupRender, or revert back to
BeginRender (as in our Count component example, above).</p><p>If no methods are
annotated with AfterRender, then no special output occurs, and the
CleanupRender phase is triggered.</p><h3
id="ComponentRendering-CleanupRender">CleanupRender</h3><p>The CleanupRender
phase (see @<a class="external-link" href="http://tapest
ry.apache.org/current/apidocs/org/apache/tapestry5/annotations/CleanupRender.html">CleanupRender</a>)
is the counterpart to SetupRender, allowing final cleanup to occur.</p><h2
id="ComponentRendering-UsingMethodNamesinsteadofAnnotations">Using Method Names
instead of Annotations</h2><p>If you prefer to avoid using annotations on your
methods, you may do so by providing specific names for your methods. The
required method name is the annotation name, with the first character
decapitalized: setupRender(), beginRender(), etc. As with annotated render
phase methods, Tapestry is flexible about visibility, return type and
parameters.</p><p>Using this mechanism, the earlier example can be rewritten
as:</p><parameter ac:name="">java</parameter><plain-text-body>package
org.example.app.components;
+</pre>
+</div></div><p>Returning false from next() causes Tapestry to re-run the
BeginRender phase, and from there, re-render the component's body (this
component does not have a template). Returning true transitions to the
CleanupRender phase.</p><p>Notice how Tapestry adapts to your methods, as
marked with the annotations. It also adapts in terms of parameters; the two
annotated methods here did not perform any output, so they did not need a
MarkupWriter.</p><p>What's really mind blowing is that the template and body of
a component will often contain ... more components! That means that many
different components will be in different phases of their own state
machine.</p><h2 id="ComponentRendering-RenderPhasesinDetail">Render Phases in
Detail</h2><p></p><div class="navmenu" style="float:right; width:50%;
background:#eee; margin:3px; padding:3px">
+<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>The SetupRender phase, like all render phases, occurs once for each
rendering of the component. If the component is inside a looping component (<a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Loop.html">Loop</a>,
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Grid.html">Grid</a>,
etc.), then the SetupRender method will be called once for <em>each</em>
iteration of the loop.</p></div></div></div><h3
id="ComponentRendering-SetupRender">SetupRender</h3><p>The SetupRender phase
(see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SetupRender.html">SetupRender</a>)
is where you can perform any one-time per-render setup for your component.
This is a good place to read component parameters and use them to set temporary
instance variables.</p><h3 id="ComponentRendering-BeginRender">BeginRender</
h3><p>The BeginRender phase (see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeginRender.html">BeginRender</a>)
occurs at the start of the rendering of the component. For components that
render a tag, the start tag should be rendered here (the close tag should be
rendered inside the AfterRender phase). The component can also prevent the
template and/or body from being rendered by returning false.</p><p>Components
may or may not have a template. If a component has a template, and the template
includes a <body> element, then the BeforeRenderBody phase will be
triggered (giving the component the option of rendering its body or
not).</p><p>If a component does not have a <body> element in its
template, then the BeforeRenderBody phase is not triggered.</p><p>If a
component does not have a template, but does have a body, the BeforeRenderBody
phase is still triggered.</p><p>If no methods are annotated with BeginRen
der, then no special output occurs during this phase, but the template (if
present) or body (if no template is present, but the component has a body) will
be rendered.</p><h3
id="ComponentRendering-BeforeRenderTemplate">BeforeRenderTemplate</h3><p>The
BeforeRenderTemplate phase (see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderTemplate.html">BeforeRenderTemplate</a>)
exists to allow a component to decorate its template (creating markup around
the template generated markup), or to allow a component to skip its
template.</p><h3
id="ComponentRendering-BeforeRenderBody">BeforeRenderBody</h3><p>The
BeforeRenderBody phase (see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/BeforeRenderBody.html">BeforeRenderBody</a>)
is associated with a component's body (the portion of its container's template
that the component occupies). The BeforeRenderBody phase al
lows the component the ability to skip the body, while still rendering the
rest of the component's template (if any).</p><p>If no methods are annotated
with BeforeRenderBody, then the body will be rendered by default. Again, this
occurs when the <body> element of the component's template is reached, or
automatically if the component has no template (but the component does have a
body).</p><h3
id="ComponentRendering-AfterRenderBody">AfterRenderBody</h3><p>The
AfterRenderBody phase (see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRenderBody.html">AfterRenderBody</a>)
is executed after the body is rendered; this only occurs for components with a
body.</p><h3 id="ComponentRendering-AfterRender">AfterRender</h3><p>The
AfterRender phase (see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/AfterRender.html">AfterRender</a>)
complements BeginRender, and is
often used to render the close tag that matches the start tag rendered in the
BeginRender phase. In any case, the AfterRender phase can continue on to
CleanupRender, or revert back to BeginRender (as in our Count component
example, above).</p><p>If no methods are annotated with AfterRender, then no
special output occurs, and the CleanupRender phase is triggered.</p><h3
id="ComponentRendering-CleanupRender">CleanupRender</h3><p>The CleanupRender
phase (see @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/CleanupRender.html">CleanupRender</a>)
is the counterpart to SetupRender, allowing final cleanup to occur.</p><h2
id="ComponentRendering-UsingMethodNamesinsteadofAnnotations">Using Method Names
instead of Annotations</h2><p>If you prefer to avoid using annotations on your
methods, you may do so by providing specific names for your methods. The
required method name is the annotation name, with the first character
decapitaliz
ed: setupRender(), beginRender(), etc. As with annotated render phase methods,
Tapestry is flexible about visibility, return type and parameters.</p><p>Using
this mechanism, the earlier example can be rewritten as:</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;">package org.example.app.components;
import org.apache.tapestry5.annotations.Parameter;
@@ -175,7 +264,9 @@ public class Count
return true;
}
}
-</plain-text-body><p>This style is a trade off: on the gain side, the code is
<em>even</em> simpler and shorter, and the method names will, by design, be
more consistent from one class to the next. The down side is that the names are
very generic, and may in some cases, be less descriptive than using annotated
methods (<code>initializeValue()</code> and <code>next()</code> are, to some
eyes, more descriptive).</p><p>You can, of course, mix and match, using
specifically named render phase methods in some cases, and annotated render
phase methods in other cases.</p><h2
id="ComponentRendering-RenderingComponents">Rendering Components</h2><p>Instead
of returning true or false, a render phase method may return a component. The
component may have been injected via the @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Component.html">Component</a>
annotation, or may have been passed to the owning component as a
parameter.</p><p>In
any case, returning a component will queue that component to be rendered
<strong>before</strong> the active component continues rendering.</p><p>The
component to render may even be from a completely different page of the
application.</p><p>Recursive rendering of components is not allowed.</p><p>This
technique allows the rendering of Tapestry pages to be <em>highly</em>
dynamic.</p><p>Returning a component instance does <strong>not</strong> short
circuit method invocation (as described below), the way returning a boolean
would. It is possible that multiple methods may return components (this is not
advised – insanity may ensue).</p><h2
id="ComponentRendering-AdditionalReturnTypes">Additional Return
Types</h2><p>Render phase methods may also return <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Block.html">Blocks</a>,
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Renderable.html">R
enderables</a> or <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/runtime/RenderCommand.html">RenderCommands</a>.</p><p>The
following component returns a Renderable in the BeginRender phase and skips
the BeforeRenderTemplate phase:</p><parameter
ac:name="lang">java</parameter><plain-text-body>public class
OutputValueComponent
+</pre>
+</div></div><p>This style is a trade off: on the gain side, the code is
<em>even</em> simpler and shorter, and the method names will, by design, be
more consistent from one class to the next. The down side is that the names are
very generic, and may in some cases, be less descriptive than using annotated
methods (<code>initializeValue()</code> and <code>next()</code> are, to some
eyes, more descriptive).</p><p>You can, of course, mix and match, using
specifically named render phase methods in some cases, and annotated render
phase methods in other cases.</p><h2
id="ComponentRendering-RenderingComponents">Rendering Components</h2><p>Instead
of returning true or false, a render phase method may return a component. The
component may have been injected via the @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Component.html">Component</a>
annotation, or may have been passed to the owning component as a
parameter.</p><p>In any ca
se, returning a component will queue that component to be rendered
<strong>before</strong> the active component continues rendering.</p><p>The
component to render may even be from a completely different page of the
application.</p><p>Recursive rendering of components is not allowed.</p><p>This
technique allows the rendering of Tapestry pages to be <em>highly</em>
dynamic.</p><p>Returning a component instance does <strong>not</strong> short
circuit method invocation (as described below), the way returning a boolean
would. It is possible that multiple methods may return components (this is not
advised – insanity may ensue).</p><h2
id="ComponentRendering-AdditionalReturnTypes">Additional Return
Types</h2><p>Render phase methods may also return <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Block.html">Blocks</a>,
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Renderable.html">Rendera
bles</a> or <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/runtime/RenderCommand.html">RenderCommands</a>.</p><p>The
following component returns a Renderable in the BeginRender phase and skips
the BeforeRenderTemplate phase:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class OutputValueComponent
{
@Parameter
private String value;
@@ -191,8 +282,11 @@ public class Count
};
}
}
-</plain-text-body><h2 id="ComponentRendering-ShortCircuiting">Short
Circuiting</h2><p>If a method returns a true or false value, this will short
circuit processing. Other methods within the phase that would ordinarily be
invoked will not be invoked.</p><p>Most render phase methods should return
void, to avoid unintentionally short circuiting other methods for the same
phase.</p><h2 id="ComponentRendering-MethodConflictsandOrdering">Method
Conflicts and Ordering</h2><p>It is possible to have multiple methods that are
annotated with the same render phase annotation. This may include methods in
the same class, or a mix of method defined in a class and inherited from other
classes.</p><h3 id="ComponentRendering-MixinsBeforeComponent">Mixins Before
Component</h3><p>When a component has <a
href="component-mixins.html">mixins</a>, then the mixins' render phase methods
execute <em>before</em> the component's render phase methods. If a mixin
extends from a base class, the mixin's parent cla
ss methods execute before the mixin subclass' render phase
methods.</p><p>Exception: Mixins whose class is annotated with @<a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/MixinAfter.html">MixinAfter</a>
are ordered <em>after</em> the component, not before.</p><p>The order in which
the mixins of a given class (@MixinAfter or mixins before) execute is
determined by the ordering constraints specified for the mixins. If no
constraints are provided, the order is undefined. See <a
href="component-mixins.html">Component Mixins</a> for more details.</p><h3
id="ComponentRendering-ParentsbeforeChild">Parents before Child</h3><p>Ordering
is always parent-first. Methods defined in the parent class are always invoked
before methods defined in the child class.</p><p>When a sub-class overrides an
render phase method of a base class, the method is only invoked once, along
with any other base class methods. The subclass can change the <em>
implementation</em> of the base class method via an override, but can't change
the <em>timing</em> of when that method is invoked. See <a
class="external-link"
href="https://issues.apache.org/jira/browse/TAPESTRY-2311">TAPESTRY-2311</a>.</p><h3
id="ComponentRendering-ReverseOrderingforAfterXXXandCleanupRender">Reverse
Ordering for AfterXXX and CleanupRender</h3><p>The After_XXX_ phases exists to
balance the Begin_XXX_ and Before_XXX_ phases. Often elements will be started
inside an earlier phase and then the elements will be ended (closed) inside the
corresponding After_XXX_ phase (with the body and template of the component
rendering between).</p><p>In order to ensure that operations occur in the
correct, and natural order, the render phase methods for these two stages are
invoked in <em>reverse order</em>:</p><ul><li>Subclass methods</li><li>Parent
class methods</li><li>Mixin subclass methods</li><li>Mixin parent class
methods</li></ul><h3 id="ComponentRendering-WithinaSingleClas
s">Within a Single Class</h3><p>Currently, rendering methods having the same
annotation within a single class are executed in alphabetical order by method
name. Methods with the same name are ordered by number of parameters. Even so,
annotating multiple methods with the same rendering phase is not a great idea.
Instead, just define one method, and have it call the other methods in the
order you desire.</p><h2 id="ComponentRendering-RenderingComments">Rendering
Comments</h2><p>Starting with version 5.3, Tapestry can optionally emit
rendering comments for all requests; these are comments such as <!--BEGIN
Index:loop (context:Index.tml, line 15)--> that can assist you in debugging
markup output on the client-side. This will significantly increase the size of
the rendered markup, but can be very helpful with complex layouts to determine
which component was responsible for which portion of the rendered
page.</p><p>Rendering comments are only available when not running in <a href="
configuration.html">production mode</a>.</p><p>To turn on rendering comments
for all requests, set the <a
href="configuration.html">tapestry.component-render-tracing-enabled</a>
configuration symbol to "true".</p><p>To turn on rendering comments only for a
particular request, add the query parameter <code>t:component-trace=true</code>
to the URL:</p><plain-text-body>
http://www.example.com/myapp/mypage?t:component-trace=true
-</plain-text-body></div>
+</pre>
+</div></div><h2 id="ComponentRendering-ShortCircuiting">Short
Circuiting</h2><p>If a method returns a true or false value, this will short
circuit processing. Other methods within the phase that would ordinarily be
invoked will not be invoked.</p><p>Most render phase methods should return
void, to avoid unintentionally short circuiting other methods for the same
phase.</p><h2 id="ComponentRendering-MethodConflictsandOrdering">Method
Conflicts and Ordering</h2><p>It is possible to have multiple methods that are
annotated with the same render phase annotation. This may include methods in
the same class, or a mix of method defined in a class and inherited from other
classes.</p><h3 id="ComponentRendering-MixinsBeforeComponent">Mixins Before
Component</h3><p>When a component has <a
href="component-mixins.html">mixins</a>, then the mixins' render phase methods
execute <em>before</em> the component's render phase methods. If a mixin
extends from a base class, the mixin's parent class met
hods execute before the mixin subclass' render phase methods.</p><p>Exception:
Mixins whose class is annotated with @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/MixinAfter.html">MixinAfter</a>
are ordered <em>after</em> the component, not before.</p><p>The order in which
the mixins of a given class (@MixinAfter or mixins before) execute is
determined by the ordering constraints specified for the mixins. If no
constraints are provided, the order is undefined. See <a
href="component-mixins.html">Component Mixins</a> for more details.</p><h3
id="ComponentRendering-ParentsbeforeChild">Parents before Child</h3><p>Ordering
is always parent-first. Methods defined in the parent class are always invoked
before methods defined in the child class.</p><p>When a sub-class overrides an
render phase method of a base class, the method is only invoked once, along
with any other base class methods. The subclass can change the <em>implem
entation</em> of the base class method via an override, but can't change the
<em>timing</em> of when that method is invoked. See <a class="external-link"
href="https://issues.apache.org/jira/browse/TAPESTRY-2311">TAPESTRY-2311</a>.</p><h3
id="ComponentRendering-ReverseOrderingforAfterXXXandCleanupRender">Reverse
Ordering for AfterXXX and CleanupRender</h3><p>The After_XXX_ phases exists to
balance the Begin_XXX_ and Before_XXX_ phases. Often elements will be started
inside an earlier phase and then the elements will be ended (closed) inside the
corresponding After_XXX_ phase (with the body and template of the component
rendering between).</p><p>In order to ensure that operations occur in the
correct, and natural order, the render phase methods for these two stages are
invoked in <em>reverse order</em>:</p><ul><li>Subclass methods</li><li>Parent
class methods</li><li>Mixin subclass methods</li><li>Mixin parent class
methods</li></ul><h3 id="ComponentRendering-WithinaSingleClass">Wit
hin a Single Class</h3><p>Currently, rendering methods having the same
annotation within a single class are executed in alphabetical order by method
name. Methods with the same name are ordered by number of parameters. Even so,
annotating multiple methods with the same rendering phase is not a great idea.
Instead, just define one method, and have it call the other methods in the
order you desire.</p><h2 id="ComponentRendering-RenderingComments">Rendering
Comments</h2><p>Starting with version 5.3, Tapestry can optionally emit
rendering comments for all requests; these are comments such as <!--BEGIN
Index:loop (context:Index.tml, line 15)--> that can assist you in debugging
markup output on the client-side. This will significantly increase the size of
the rendered markup, but can be very helpful with complex layouts to determine
which component was responsible for which portion of the rendered
page.</p><p>Rendering comments are only available when not running in <a
href="config
uration.html">production mode</a>.</p><p>To turn on rendering comments for all
requests, set the <a
href="configuration.html">tapestry.component-render-tracing-enabled</a>
configuration symbol to "true".</p><p>To turn on rendering comments only for a
particular request, add the query parameter <code>t:component-trace=true</code>
to the URL:</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;">
http://www.example.com/myapp/mypage?t:component-trace=true
+</pre>
+</div></div></div>
</div>
<div class="clearer"></div>