Modified: websites/production/tapestry/content/component-templates.html
==============================================================================
--- websites/production/tapestry/content/component-templates.html (original)
+++ websites/production/tapestry/content/component-templates.html Wed Sep 20
12:29:16 2017
@@ -27,6 +27,14 @@
</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/shBrushXml.js'
type='text/javascript'></script>
+ <script>
+ SyntaxHighlighter.defaults['toolbar'] = false;
+ SyntaxHighlighter.all();
+ </script>
<link href="/styles/style.css" rel="stylesheet" type="text/css"/>
@@ -67,10 +75,109 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><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
("component-templates","components","rendering","response") and space =
currentSpace()</parameter></rich-text-body><p>Under Tapestry, a
<strong>component template</strong> is a file that contains the markup for a
component.</p><p>Component templates are <em>well formed XML documents</em>.
That means that every open tag must have a matching close tag, every attribute
must be quoted, and so forth.</p><p><em>Note: At runtime, Tapestry parses the
documents and only checks for wellformedness. Even when the document has a DTD
or schema, there are no validity checks.</em></p><p>For the most part, t
hese templates are standard HTML/XHTML; Tapestry extensions to ordinary markup
are provided in the form of a Tapestry namespace:</p><parameter
ac:name="language">xml</parameter><parameter ac:name="title">A template for a
page</parameter><plain-text-body><html t:type="layout"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+ <div id="ConfluenceContent"><div class="aui-label"
style="float:right" title="Related Articles">
+
+
+
+
+
+
+
+
+<h3>Related Articles</h3>
+
+<ul class="content-by-label"><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a 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="component-reference.html">Component
Reference</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-libraries.html">Component
Libraries</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="templating-and-markup-faq.html">Templating
and Markup 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="component-classes.html">Component Classes</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><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="configuration.html">Configuration</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="component-parameters.html">Component
Parameters</a>
+
+
+ </div>
+ </li><li>
+ <div>
+ <span class="icon aui-icon aui-icon-small
aui-iconfont-page-default" title="Page">Page:</span> </div>
+
+ <div class="details">
+ <a href="assets.html">Assets</a>
+
+
+ </div>
+ </li></ul>
+</div>
+
+
+<p>Under Tapestry, a <strong>component template</strong> is a file that
contains the markup for a component.</p><p>Component templates are <em>well
formed XML documents</em>. That means that every open tag must have a matching
close tag, every attribute must be quoted, and so forth.</p><p><em>Note: At
runtime, Tapestry parses the documents and only checks for wellformedness. Even
when the document has a DTD or schema, there are no validity
checks.</em></p><p>For the most part, these templates are standard HTML/XHTML;
Tapestry extensions to ordinary markup are provided in the form of a Tapestry
namespace:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>A
template for a page</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><html t:type="layout"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<h1>Bonjour from HelloWorld component.</h1>
</html>
-</plain-text-body><rich-text-body> </rich-text-body><p>We'll cover the
specific content of templates shortly, but first a few details about connecting
a component to its template.</p><h2
id="ComponentTemplates-TemplateLocation">Template Location</h2><p>A component
template shares the same name as its corresponding class file, but with a
".tml" ending (i.e., <strong>T</strong>apestry <strong>M</strong>arkup
<strong>L</strong>anguage), and is stored in the same package as the
corresponding component class.</p><p>Under a typical Maven directory structure,
the Java class and template files for a <em>component</em> might be:</p><div
class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>Java class:</strong></p></td><td
colspan="1" rowspan="1"
class="confluenceTd"><p><code>src/main/java/org/example/myapp/components/MyComponent.java</code></p></td></tr><tr><td
colspan="1" rowspan="1" class="confluenceTd"><p><strong>Temp
late:</strong></p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>src/main/resources/org/example/myapp/components/MyComponent.tml</code></p></td></tr></tbody></table></div><p>Likewise,
the Java class and template files for a <em>page</em> might be:</p><div
class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>Java class:</strong></p></td><td
colspan="1" rowspan="1"
class="confluenceTd"><p><code>src/main/java/org/example/myapp/pages/MyPage.java</code></p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p><strong>Template:</strong></p></td><td colspan="1"
rowspan="1"
class="confluenceTd"><p><code>src/main/resources/org/example/myapp/pages/MyPage.tml</code></p></td></tr></tbody></table></div><p>The
template and the compiled class will be packaged together in the
WEB-INF/classes folder of the application WAR.</p><p>For <em>pages</em> (but
not other components), a second location will be sear
ched: in the web application context. The location is based on the logical
name of the page, in the previous example, the template would be
<code>MyPage.tml</code> in the root folder of the web application.</p><p>A
template on the classpath takes precedence over a file in the web application
context.</p><rich-text-body><p>Allowing pages to store their template in the
web context is a feature that may go away at some point. It was included as a
way for HTML designers to edit template directly and live preview the template
directly, without executing the Tapestry application. This comes with a large
number of limitations and leads to a false sense of security that a template
that previews correctly will render properly (this is not always the
case).</p></rich-text-body><h2
id="ComponentTemplates-TemplateLocalization">Template Localization</h2><p>Main
Article: <a href="localization.html">Localization</a></p><p>Templates are
handled in much the same way as individual files of a compone
nt's message catalog: the effective locale is inserted into the name of the
file. Thus a German users will see the content generated from
<code>MyPage_de.tml</code> and French users will see content generated from
<code>MyPage_fr.tml</code>. When no specific localization is available, the
default location (<code>MyPage.tml</code>) is used.</p><rich-text-body><p>It is
necessary to <a href="configuration.html">enable support for a locale</a>
before Tapestry will attempt to localize to that locale. This requires
configuration in your application module; if you are using the Tapestry
Quickstart archetype, only locale "en" will be enabled by
default.</p></rich-text-body><p><parameter
ac:name="">doctypes</parameter></p><h2
id="ComponentTemplates-TemplateDoctypes">Template Doctypes</h2><p>As mentioned
above, component templates are well-formed XML documents. This means that if
you want to use any <a class="external-link"
href="http://www.w3.org/TR/html401/sgml/entities.html" rel="nofollo
w">Named HTML entities</a> (such as &amp; &lt; &gt; &copy;),
you must use an <a class="external-link"
href="http://www.w3.org/QA/2002/04/valid-dtd-list.html" rel="nofollow">HTML or
XHTML doctype</a> in your template <em>(starting in 5.3, this is more-or-less
automatic, see notes below)</em>. If you choose to use (X)HTML doctypes in your
templates, they will be passed on to the client in the resultant (X)HTML. Note
that if your pages are composed of multiple components, each with a template,
and each template contains a doctype declaration, only the first doctype
encountered by the template parser will be passed on to the client.</p><p>It
should also be noted that even though <strong>X</strong>HTML DTDs are valid XML
DTDs, HTML DTDs aren't. This means that HTML doctypes cannot be used by XML
parsers. Tapestry works around this limitation internally by using XHTML DTDs
to parse templates that use HTML DTDs. This internal mapping is possible
because XHTML 1.0 is nothin
g more than "a reformulation of the three HTML 4 document types as
applications of XML 1.0," <a class="external-link"
href="http://www.w3.org/TR/xhtml1/#xhtml" rel="nofollow">as per the W3C</a>.
Don't worry though – the original HTML 4 doctype will still be emitted to
the client!</p><p>The following are the most common (X)HTML
doctypes:</p><parameter ac:name="">xml</parameter><plain-text-body><!DOCTYPE
html>
+</pre>
+</div></div><div class="sectionMacro"><div
class="sectionMacroRow"> </div></div><p>We'll cover the specific content
of templates shortly, but first a few details about connecting a component to
its template.</p><h2 id="ComponentTemplates-TemplateLocation">Template
Location</h2><p>A component template shares the same name as its corresponding
class file, but with a ".tml" ending (i.e., <strong>T</strong>apestry
<strong>M</strong>arkup <strong>L</strong>anguage), and is stored in the same
package as the corresponding component class.</p><p>Under a typical Maven
directory structure, the Java class and template files for a <em>component</em>
might be:</p><div class="table-wrap"><table
class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p><strong>Java class:</strong></p></td><td colspan="1"
rowspan="1"
class="confluenceTd"><p><code>src/main/java/org/example/myapp/components/MyComponent.java</code></p></td></tr><tr><td
colspan="1" rowspan="1" class="c
onfluenceTd"><p><strong>Template:</strong></p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p><code>src/main/resources/org/example/myapp/components/MyComponent.tml</code></p></td></tr></tbody></table></div><p>Likewise,
the Java class and template files for a <em>page</em> might be:</p><div
class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>Java class:</strong></p></td><td
colspan="1" rowspan="1"
class="confluenceTd"><p><code>src/main/java/org/example/myapp/pages/MyPage.java</code></p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p><strong>Template:</strong></p></td><td colspan="1"
rowspan="1"
class="confluenceTd"><p><code>src/main/resources/org/example/myapp/pages/MyPage.tml</code></p></td></tr></tbody></table></div><p>The
template and the compiled class will be packaged together in the
WEB-INF/classes folder of the application WAR.</p><p>For <em>pages</em> (but
not other components), a
second location will be searched: in the web application context. The location
is based on the logical name of the page, in the previous example, the template
would be <code>MyPage.tml</code> in the root folder of the web
application.</p><p>A template on the classpath takes precedence over a file in
the web application context.</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>Allowing pages to store their
template in the web context is a feature that may go away at some point. It was
included as a way for HTML designers to edit template directly and live preview
the template directly, without executing the Tapestry application. This comes
with a large number of limitations and leads to a false sense of security that
a template that previews correctly will render properly (this is not always the
case).</p>
</div></div><h2 id="ComponentTemplates-TemplateLocalization">Template
Localization</h2><p>Main Article: <a
href="localization.html">Localization</a></p><p>Templates are handled in much
the same way as individual files of a component's message catalog: the
effective locale is inserted into the name of the file. Thus a German users
will see the content generated from <code>MyPage_de.tml</code> and French users
will see content generated from <code>MyPage_fr.tml</code>. When no specific
localization is available, the default location (<code>MyPage.tml</code>) is
used.</p><div class="confluence-information-macro
confluence-information-macro-information"><span class="aui-icon aui-icon-small
aui-iconfont-info confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>It is necessary to <a
href="configuration.html">enable support for a locale</a> before Tapestry will
attempt to localize to that locale. This requires configuration in your
application modul
e; if you are using the Tapestry Quickstart archetype, only locale "en" will
be enabled by default.</p></div></div><p><span class="confluence-anchor-link"
id="ComponentTemplates-doctypes"></span></p><h2
id="ComponentTemplates-TemplateDoctypes">Template Doctypes</h2><p>As mentioned
above, component templates are well-formed XML documents. This means that if
you want to use any <a class="external-link"
href="http://www.w3.org/TR/html401/sgml/entities.html" rel="nofollow">Named
HTML entities</a> (such as &amp; &lt; &gt; &copy;), you must
use an <a class="external-link"
href="http://www.w3.org/QA/2002/04/valid-dtd-list.html" rel="nofollow">HTML or
XHTML doctype</a> in your template <em>(starting in 5.3, this is more-or-less
automatic, see notes below)</em>. If you choose to use (X)HTML doctypes in your
templates, they will be passed on to the client in the resultant (X)HTML. Note
that if your pages are composed of multiple components, each with a template,
and each tem
plate contains a doctype declaration, only the first doctype encountered by
the template parser will be passed on to the client.</p><p>It should also be
noted that even though <strong>X</strong>HTML DTDs are valid XML DTDs, HTML
DTDs aren't. This means that HTML doctypes cannot be used by XML parsers.
Tapestry works around this limitation internally by using XHTML DTDs to parse
templates that use HTML DTDs. This internal mapping is possible because XHTML
1.0 is nothing more than "a reformulation of the three HTML 4 document types as
applications of XML 1.0," <a class="external-link"
href="http://www.w3.org/TR/xhtml1/#xhtml" rel="nofollow">as per the W3C</a>.
Don't worry though – the original HTML 4 doctype will still be emitted to
the client!</p><p>The following are the most common (X)HTML doctypes:</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>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
@@ -83,7 +190,8 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
-</plain-text-body><p>The first one is for <a class="external-link"
href="http://en.wikipedia.org/wiki/HTML5" rel="nofollow">HTML5</a> and is
recommended for Tapestry 5.2.5 and later. In versions prior to Tapestry 5.2.5,
Tapestry didn't support the HTML5 doctype directly (but see the comments at <a
class="external-link"
href="https://issues.apache.org/jira/browse/TAP5-1040">TAP5-1040</a> for a
work-around).</p>
+</pre>
+</div></div><p>The first one is for <a class="external-link"
href="http://en.wikipedia.org/wiki/HTML5" rel="nofollow">HTML5</a> and is
recommended for Tapestry 5.2.5 and later. In versions prior to Tapestry 5.2.5,
Tapestry didn't support the HTML5 doctype directly (but see the comments at <a
class="external-link"
href="https://issues.apache.org/jira/browse/TAP5-1040">TAP5-1040</a> for a
work-around).</p>
<div class="confluence-information-macro
confluence-information-macro-information"><p class="title">Added in
5.3</p><span class="aui-icon aui-icon-small aui-iconfont-info
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body">
</div></div>
@@ -93,7 +201,8 @@
<p>A template without a <!DOCTYPE> is parsed as if it had the HTML
Doctype (<code><!DOCTYPE html></code>). In fact, Tapestry creates an
in-memory copy of the template that includes the doctype.</p>
<p>A template with the HTML Doctype (<code><!DOCTYPE html></code>) is
parsed <em>as if</em> it had the XHTML transitional Doctype. In fact, Tapestry
creates an in-memory copy of the template that replaces the <!DOCTYPE>
line. This applies as well to a template without any Doctype, in which case the
XHTML transitional Doctype is inserted at the top. In either case, this means
you can use arbitrary HTML entities, such as <code>&copy;</code> or
<code>&nbsp;</code> without seeing the XML parsing errors that would occur
in earlier releases.</p>
-</div><h2 id="ComponentTemplates-TheTapestryNamespace">The Tapestry
Namespace</h2><p>Component templates should include the Tapestry namespace,
defining it in the root element of the template.</p><parameter
ac:name="language">xml</parameter><plain-text-body><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
+</div><h2 id="ComponentTemplates-TheTapestryNamespace">The Tapestry
Namespace</h2><p>Component templates should include the Tapestry namespace,
defining it in the root element of the 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;"><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd">
<head>
<title>Hello World Page</title>
</head>
@@ -101,7 +210,9 @@
<h1>Hello World</h1>
</body>
</html>
-</plain-text-body><p>This defines the namespace using the standard prefix,
"t:". The examples on this page all assume the use of the standard
prefix.</p><p>For backwards compatibility, you may continue to use the old
namespace URIs: <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">http://tapestry.apache.org/schema/tapestry_5_0_0.xsd</a>
or <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">http://tapestry.apache.org/schema/tapestry_5_1_0.xsd</a> or
 <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_3.xsd">http://tapestry.apache.org/schema/tapestry_5_3.xsd</a></p><pre> </pre><p> However,
the following elements added, as part of Tapestry 5.1, will not work with the
5_0_0.xsd:</p><ul><li>The <t:remove>
Element</li><li><t:content></li><li><t:extension-point></li><li><t:extend></li><li><t:replace></li></ul><p>The
5_3.xsd fixes some minor bug
s in the 5_1_0.xsd, but is functionally equivalent; 5_3.xsd and 5_4.xsd are
identical.</p><h2 id="ComponentTemplates-TapestryElements">Tapestry
Elements</h2><p>Tapestry elements are elements defined using the Tapestry
namespace prefix (usually "t:").</p><p>All other elements in your templates
should be in the default namespace, with no prefix (with the possible exception
of any Library Namespaces (described <a
href="component-templates.html">below</a>).</p><p>There are a certain number of
Tapestry elements, listed below, that act as template directives; beyond that,
any element in the Tapestry namespace will be a Tapestry component.</p><h3
id="ComponentTemplates-The<t:body>Element">The <t:body>
Element</h3><p>In many cases, a component is designed to have its template
integrate with, or "wrap around", the containing component.</p><p>The
<t:body> element is used to identify where, within a component's
template, its body (from the container's template) is to be rend
ered.</p><p>Components have control over if, and even how often, their body is
rendered.</p><p>The following example is a <a
href="layout-component.html">Layout component</a>, which adds basic HTML
elements <em>around</em> the page-specific content:</p><parameter
ac:name="language">xml</parameter><plain-text-body><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+</pre>
+</div></div><p>This defines the namespace using the standard prefix, "t:". The
examples on this page all assume the use of the standard prefix.</p><p>For
backwards compatibility, you may continue to use the old namespace URIs: <a
class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">http://tapestry.apache.org/schema/tapestry_5_0_0.xsd</a>
or <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">http://tapestry.apache.org/schema/tapestry_5_1_0.xsd</a> or
 <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_3.xsd">http://tapestry.apache.org/schema/tapestry_5_3.xsd</a></p><pre> </pre><p> However,
the following elements added, as part of Tapestry 5.1, will not work with the
5_0_0.xsd:</p><ul><li>The <t:remove>
Element</li><li><t:content></li><li><t:extension-point></li><li><t:extend></li><li><t:replace></li></ul><p>The
5_3.xsd fixes some minor bugs in t
he 5_1_0.xsd, but is functionally equivalent; 5_3.xsd and 5_4.xsd are
identical.</p><h2 id="ComponentTemplates-TapestryElements">Tapestry
Elements</h2><p>Tapestry elements are elements defined using the Tapestry
namespace prefix (usually "t:").</p><p>All other elements in your templates
should be in the default namespace, with no prefix (with the possible exception
of any Library Namespaces (described <a
href="component-templates.html">below</a>).</p><p>There are a certain number of
Tapestry elements, listed below, that act as template directives; beyond that,
any element in the Tapestry namespace will be a Tapestry component.</p><h3
id="ComponentTemplates-The<t:body>Element">The <t:body>
Element</h3><p>In many cases, a component is designed to have its template
integrate with, or "wrap around", the containing component.</p><p>The
<t:body> element is used to identify where, within a component's
template, its body (from the container's template) is to be rendered.<
/p><p>Components have control over if, and even how often, their body is
rendered.</p><p>The following example is a <a
href="layout-component.html">Layout component</a>, which adds basic HTML
elements <em>around</em> the page-specific content:</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;"><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<head>
<title>My Tapestry Application</title>
</head>
@@ -109,12 +220,16 @@
<t:body/>
</body>
</html>
-</plain-text-body><p>That "<t:body/>" element marks where the containing
page's content will be inserted. A page would then use this component as
follow:</p><parameter
ac:name="language">xml</parameter><plain-text-body><html t:type="layout"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
+</pre>
+</div></div><p>That "<t:body/>" element marks where the containing
page's content will be inserted. A page would then use this component as
follow:</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;"><html t:type="layout"
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
My Page Specific Content
</html>
-</plain-text-body><p>When the page renders, the page's template and the Layout
component's template are merged together:</p><parameter
ac:name="language">xml</parameter><plain-text-body><html>
+</pre>
+</div></div><p>When the page renders, the page's template and the Layout
component's template are merged together:</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;"><html>
<head>
<title>My Tapestry Application</title>
</head>
@@ -122,15 +237,25 @@
My Page Specific Content
</body>
</html>
-</plain-text-body><rich-text-body><p>Tapestry 4 users will recognize the
<t:body> element as a replacement for the RenderBody
component.</p></rich-text-body><h3
id="ComponentTemplates-The<t:container>Element">The <t:container>
Element</h3><p>A <t:container> element contains markup without being
considered part of the template. This is useful for components that render
several top level tags, for example, a component that renders several columns
within a table row:</p><parameter
ac:name="language">xml</parameter><plain-text-body><t:container
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+</pre>
+</div></div><div class="confluence-information-macro
confluence-information-macro-information"><span class="aui-icon aui-icon-small
aui-iconfont-info confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Tapestry 4 users will recognize
the <t:body> element as a replacement for the RenderBody
component.</p></div></div><h3
id="ComponentTemplates-The<t:container>Element">The <t:container>
Element</h3><p>A <t:container> element contains markup without being
considered part of the template. This is useful for components that render
several top level tags, for example, a component that renders several columns
within a table row:</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:container
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<td>${label}</td>
<td>${value}</td>
</t:container>
-</plain-text-body><p>This component only makes sense when used inside a
<tr> element of its container's template.</p><p>Without the
<t:container> element, there would be no way to create a valid XML
document as the template, because XML documents must always have a single root
element.</p><p><parameter ac:name="name">block</parameter></p><h3
id="ComponentTemplates-The<t:block>Element">The <t:block>
Element</h3><p>A <t:block> is a container of a portion of the component
template. A block does not normally render; any component or contents you put
inside a block will not ordinarily be rendered. However, by injecting the block
you have precise control over when and if the content renders.</p><p>A block
may be anonymous, or it may have an id (specified with the id attribute). Only
blocks with an id may be <a href="injection.html">injected</a> into the
component.</p><rich-text-body><p>A <t:block> must be in the Tapestry
namespace, but the id attribute
should not be. This is different from components in the template, where the
t:id attribute that defines the component id <em>must</em> be in the Tapestry
namespace.</p></rich-text-body><p>Ids must be valid Java identifiers: start
with a letter, and contain only letters, numbers and underscores.</p><h3
id="ComponentTemplates-The<t:parameter>Element">The <t:parameter>
Element</h3><rich-text-body><p>This element was deprecated starting in Tapestry
5.1 and <em>removed</em> in 5.3. Use <em><a
href="component-templates.html">parameter namespaces</a></em> (below)
instead.</p></rich-text-body><p>A <parameter> element is a special kind
of block. It is placed inside the body of an embedded component. The block
defined by the <parameter> is passed to the component. <parameter>
includes a mandatory name attribute to identify which parameter of the
component to bind.</p><h3
id="ComponentTemplates-The<t:content>Element">The <t:content>
Element</h3><p>&l
t;t:content> marks a portion of the template as the actual template
<em>content</em>; any markup outside the <t:content> element is ignored.
This is useful for eliminating portions of the template that exist to support
WYSIWYG preview of the template.</p><p><t:content> elements may not
nest.</p><p>Support for the <t:content> element was adding in Tapestry
release 5.1. You must use the <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">http://tapestry.apache.org/schema/tapestry_5_1_0.xsd</a>
or <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_3.xsd">http://tapestry.apache.org/schema/tapestry_5_3.xsd</a>
namespace URI for content to be recognized (otherwise you will see an error
about a missing "content" component).</p><h3
id="ComponentTemplates-<t:remove>"><t:remove></h3><p>Marks a
portion of the template for removal; it is as if the remove element and
everything inside it simply was not p
art of the template. This is used as a kind of server-side only comment
(normal HTML/XML comments are included in a page render response), or to
temporarily eliminate a portion of the template. As far as Tapestry is
concerned, the contents of the <remove> element do not exist (including
validating consistency between components defined or injected in the Java class
and the template).</p><p>Support for the <t:remove> element was added in
Tapestry release 5.1. You must use the <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">http://tapestry.apache.org/schema/tapestry_5_1_0.xsd</a>
or <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_3.xsd">http://tapestry.apache.org/schema/tapestry_5_3.xsd</a>
namespace URI for remove to be recognized (otherwise you will see an error
about a missing "remove" component).</p><p><parameter
ac:name="">Expansions</parameter></p><h2
id="ComponentTemplates-Expansions">Expansions</h2>
<p>Another option when rendering output is the use of <em>expansions</em>.
Expansions are special strings that may be embedded in template bodies, and
borrow some syntax from the <a class="external-link"
href="http://ant.apache.org">Ant</a> build tool.</p><parameter
ac:name="language">xml</parameter><plain-text-body> Welcome, ${userId}!
-</plain-text-body><p>Here, <code>${userId</code>} is the expansion. In this
example, the userId property of the component is extracted, converted to a
string, and streamed into the output.</p><p>Expansions are allowed inside text,
and inside attributes of ordinary elements, and component elements. For
example:</p><parameter ac:name="language">xml</parameter><plain-text-body>
<img
src="${request.contextPath}/images/catalog/product_${productId}.png"/>
-</plain-text-body><p>In this hypothetical example, the component class is
providing a request property and a productId property, and these are being used
inside the template to assemble the src attribute of the <img> element.
This is component-like behavior without actual components.</p><p>Under the
covers, expansions are the same as <a
href="component-parameters.html">parameter bindings</a>. The default binding
prefix for expansions is "prop:" (that is, the name of a property or a <a
href="property-expressions.html">property expression</a>), but other binding
prefixes are useful, especially "message:" (to access a localized message from
the component's message catalog).</p><rich-text-body><p>Do not use expansions
in component parameters if the parameter's default or explicit binding prefix
is "prop:" or "var:". Expansions convert the value to an immutable string,
resulting in a runtime exception if the component tries to update the value.
Even for read-only parameters, expa
nsions are not as desirable, since they always convert to a string, and from
there to the parameter's declared
type.</p></rich-text-body><rich-text-body><p>Tapestry 4 users will note that
expansions are a concise, easy replacement for the Insert component, and for
the <span key="..."> directive.</p></rich-text-body><p>Note that
expansions escape any HTML reserved characters. Specifically, any less-than
(<), greater than (>) and ampersand (&) are replaced with &lt;,
&gt; and &amp; respectively. That is usually what you want. However, if
your property contains HTML that you want rendered as raw markup, you can use
the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/OutputRaw.html">OutputRaw</a>
component instead, like this: <code><t:OutputRaw
value="someContent"/></code> where <code>someContent</code> is a property
containing HTML markup.</p><p><em>Caution: if the content comes from an
untrusted source (like a public user), be sure to filter it before providing
it to OutputRaw. Otherwise you've got a potential cross-site scripting
vulnerability.</em></p><h2 id="ComponentTemplates-EmbeddedComponents">Embedded
Components</h2><p>An embedded component is identified within the template as an
element in the t: namespace. Example:</p><parameter
ac:name="language">xml</parameter><plain-text-body> You have
${cartItems.size()} items in your cart.
+</pre>
+</div></div><p>This component only makes sense when used inside a <tr>
element of its container's template.</p><p>Without the <t:container>
element, there would be no way to create a valid XML document as the template,
because XML documents must always have a single root element.</p><p></p><h3
id="ComponentTemplates-The<t:block>Element">The <t:block>
Element</h3><p>A <t:block> is a container of a portion of the component
template. A block does not normally render; any component or contents you put
inside a block will not ordinarily be rendered. However, by injecting the block
you have precise control over when and if the content renders.</p><p>A block
may be anonymous, or it may have an id (specified with the id attribute). Only
blocks with an id may be <a href="injection.html">injected</a> into the
component.</p><div class="confluence-information-macro
confluence-information-macro-warning"><span class="aui-icon aui-icon-small
aui-iconfont-error conflu
ence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>A <t:block> must be in the
Tapestry namespace, but the id attribute should not be. This is different from
components in the template, where the t:id attribute that defines the component
id <em>must</em> be in the Tapestry namespace.</p></div></div><p>Ids must be
valid Java identifiers: start with a letter, and contain only letters, numbers
and underscores.</p><h3
id="ComponentTemplates-The<t:parameter>Element">The <t:parameter>
Element</h3><div class="confluence-information-macro
confluence-information-macro-note"><span class="aui-icon aui-icon-small
aui-iconfont-warning confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>This element was deprecated
starting in Tapestry 5.1 and <em>removed</em> in 5.3. Use <em><a
href="component-templates.html">parameter namespaces</a></em> (below)
instead.</p></div></div><p>A <parameter> element is a
special kind of block. It is placed inside the body of an embedded component.
The block defined by the <parameter> is passed to the component.
<parameter> includes a mandatory name attribute to identify which
parameter of the component to bind.</p><h3
id="ComponentTemplates-The<t:content>Element">The <t:content>
Element</h3><p><t:content> marks a portion of the template as the actual
template <em>content</em>; any markup outside the <t:content> element is
ignored. This is useful for eliminating portions of the template that exist to
support WYSIWYG preview of the template.</p><p><t:content> elements may
not nest.</p><p>Support for the <t:content> element was adding in
Tapestry release 5.1. You must use the <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">http://tapestry.apache.org/schema/tapestry_5_1_0.xsd</a>
or <a class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_3.xsd">ht
tp://tapestry.apache.org/schema/tapestry_5_3.xsd</a> namespace URI for content
to be recognized (otherwise you will see an error about a missing "content"
component).</p><h3
id="ComponentTemplates-<t:remove>"><t:remove></h3><p>Marks a
portion of the template for removal; it is as if the remove element and
everything inside it simply was not part of the template. This is used as a
kind of server-side only comment (normal HTML/XML comments are included in a
page render response), or to temporarily eliminate a portion of the template.
As far as Tapestry is concerned, the contents of the <remove> element do
not exist (including validating consistency between components defined or
injected in the Java class and the template).</p><p>Support for the
<t:remove> element was added in Tapestry release 5.1. You must use the <a
class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">http://tapestry.apache.org/schema/tapestry_5_1_0.xsd</a>
or <a
class="external-link"
href="http://tapestry.apache.org/schema/tapestry_5_3.xsd">http://tapestry.apache.org/schema/tapestry_5_3.xsd</a>
namespace URI for remove to be recognized (otherwise you will see an error
about a missing "remove" component).</p><p><span class="confluence-anchor-link"
id="ComponentTemplates-Expansions"></span></p><h2
id="ComponentTemplates-Expansions">Expansions</h2><p>Another option when
rendering output is the use of <em>expansions</em>. Expansions are special
strings that may be embedded in template bodies, and borrow some syntax from
the <a class="external-link" href="http://ant.apache.org">Ant</a> build
tool.</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;"> Welcome, ${userId}!
+</pre>
+</div></div><p>Here, <code>${userId</code>} is the expansion. In this example,
the userId property of the component is extracted, converted to a string, and
streamed into the output.</p><p>Expansions are allowed inside text, and inside
attributes of ordinary elements, and component elements. For example:</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
src="${request.contextPath}/images/catalog/product_${productId}.png"/>
+</pre>
+</div></div><p>In this hypothetical example, the component class is providing
a request property and a productId property, and these are being used inside
the template to assemble the src attribute of the <img> element. This is
component-like behavior without actual components.</p><p>Under the covers,
expansions are the same as <a href="component-parameters.html">parameter
bindings</a>. The default binding prefix for expansions is "prop:" (that is,
the name of a property or a <a href="property-expressions.html">property
expression</a>), but other binding prefixes are useful, especially "message:"
(to access a localized message from the component's message catalog).</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>Do not use expansions in component
parameters if the parameter's default or explicit
binding prefix is "prop:" or "var:". Expansions convert the value to an
immutable string, resulting in a runtime exception if the component tries to
update the value. Even for read-only parameters, expansions are not as
desirable, since they always convert to a string, and from there to the
parameter's declared type.</p></div></div><div
class="confluence-information-macro
confluence-information-macro-information"><span class="aui-icon aui-icon-small
aui-iconfont-info confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Tapestry 4 users will note that
expansions are a concise, easy replacement for the Insert component, and for
the <span key="..."> directive.</p></div></div><p>Note that expansions
escape any HTML reserved characters. Specifically, any less-than (<),
greater than (>) and ampersand (&) are replaced with &lt;, &gt;
and &amp; respectively. That is usually what you want. However, if your
property contains H
TML that you want rendered as raw markup, you can use the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/OutputRaw.html">OutputRaw</a>
component instead, like this: <code><t:OutputRaw
value="someContent"/></code> where <code>someContent</code> is a property
containing HTML markup.</p><p><em>Caution: if the content comes from an
untrusted source (like a public user), be sure to filter it before providing it
to OutputRaw. Otherwise you've got a potential cross-site scripting
vulnerability.</em></p><h2 id="ComponentTemplates-EmbeddedComponents">Embedded
Components</h2><p>An embedded component is identified within the template as an
element in the t: namespace. Example:</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;"> You have ${cartItems.size()} items in your cart.
<t:actionlink t:id="clear">Remove All</t:actionlink>.
-</plain-text-body><p>The element name, "actionlink" is used to select the type
of component, ActionLink.</p><rich-text-body><p>As elsewhere, Tapestry is
insensitive to case when mapping from a component type to a component
class.</p></rich-text-body><p>Embedded components may have two
Tapestry-specific <a
href="component-parameters.html">parameters</a>:</p><ul><li>id: A unique id for
the component (within its container).</li><li>mixins: An optional comma
separated list of mixins for the the component.</li></ul><p>These attributes
are specified inside the t: namespace (i.e.,
<code>t:id="clear"</code>).</p><p>If the id attribute is omitted, Tapestry will
assign a unique id for the element.</p><rich-text-body><p>Non-trivial
components should always be assigned a specific id, rather than letting
Tapestry do it. You'll end up with shorter, more readable URLs and code that's
easier to debug, because it will be more obvious how the request URL maps to
your pages and components. This is ev
en more strongly encouraged for form control components, where the component
id will usually be the same as the query parameter that stores the value
provided by the end user.</p></rich-text-body><p>Ids must be valid Java
identifiers: start with a letter, and contain only letters, numbers and
underscores.</p><p>Any other attributes are used to <a
href="component-parameters.html">bind parameters of the component</a>. These
may be formal parameters or informal parameters. Formal parameters will have a
default binding prefix (usually "prop:"). Informal parameters will be assumed
to be literals (i.e., the "literal:" binding prefix).</p><p>Use of the t:
prefix is optional for all other attributes. Some users implement a build
process where the Tapestry template files are validated ... in that case, any
Tapestry-specific attributes, not defined by the underlying DTD or schema,
should be in the Tapestry namespace, to avoid validation errors.</p><p>The open
and close tags of a Tapestry com
ponent element define the <strong>body</strong> of the component. It is quite
common for additional components to be <strong>enclosed</strong> in the body of
another component:</p><parameter
ac:name="language">xml</parameter><plain-text-body><t:form>
+</pre>
+</div></div><p>The element name, "actionlink" is used to select the type of
component, ActionLink.</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>As elsewhere, Tapestry is
insensitive to case when mapping from a component type to a component
class.</p></div></div><p>Embedded components may have two Tapestry-specific <a
href="component-parameters.html">parameters</a>:</p><ul><li>id: A unique id for
the component (within its container).</li><li>mixins: An optional comma
separated list of mixins for the the component.</li></ul><p>These attributes
are specified inside the t: namespace (i.e.,
<code>t:id="clear"</code>).</p><p>If the id attribute is omitted, Tapestry will
assign a unique id for the element.</p><div class="confluence-information-macro
confluence-information-macro-note"><span class="aui-ico
n aui-icon-small aui-iconfont-warning
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>Non-trivial components should
always be assigned a specific id, rather than letting Tapestry do it. You'll
end up with shorter, more readable URLs and code that's easier to debug,
because it will be more obvious how the request URL maps to your pages and
components. This is even more strongly encouraged for form control components,
where the component id will usually be the same as the query parameter that
stores the value provided by the end user.</p></div></div><p>Ids must be valid
Java identifiers: start with a letter, and contain only letters, numbers and
underscores.</p><p>Any other attributes are used to <a
href="component-parameters.html">bind parameters of the component</a>. These
may be formal parameters or informal parameters. Formal parameters will have a
default binding prefix (usually "prop:"). Informal parameters will be assumed
to be liter
als (i.e., the "literal:" binding prefix).</p><p>Use of the t: prefix is
optional for all other attributes. Some users implement a build process where
the Tapestry template files are validated ... in that case, any
Tapestry-specific attributes, not defined by the underlying DTD or schema,
should be in the Tapestry namespace, to avoid validation errors.</p><p>The open
and close tags of a Tapestry component element define the <strong>body</strong>
of the component. It is quite common for additional components to be
<strong>enclosed</strong> in the body of another component:</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:form>
<t:errors/>
<t:label for="userId"/>
<t:textfield t:id="userId"/>
@@ -140,7 +265,9 @@
<br/>
<input type="submit" value="Login"/>
</t:form>
-</plain-text-body><p>In this example, the <t:form> component's body
contains the other components. Structurally, all of these components (the Form,
Errors, Label, etc.) are peers: children of the page. They are all
<em>embedded</em> within the page. The Errors, Label, TextField and so forth
are <em>enclosed</em> within the Form's body ... meaning that the Form controls
if, when, and under what circumstances those components will render.</p><p>In
some cases, components require some kind of enclosure; for example, all of the
field control components (such as TextField) will throw a runtime exception if
not enclosed by a Form component.</p><p>It is possible to place Tapestry
components in sub-packages. For example, your application may have a package
org.example.myapp.components.ajax.Dialog. This component's normal type name is
"ajax/dialog" (because it is in the ajax sub-folder). This name is problematic,
as it is not valid to define an XML element with an element name <code><
;t:ajax/dialog></code>. Instead, just replace the slashes with periods:
<code><t:ajax.dialog></code>. Library namespaces (described in the next
section) are a preferred way of handling components in
sub-folders.</p><rich-text-body><p>When using a component library, the library
will map its components to a <em>virtual sub-folder</em> of the application.
The same naming mechanism works whether its is a real sub-folder or a component
library sub-folder.</p></rich-text-body><p><parameter
ac:name="">LibraryNamespaces</parameter></p><h2
id="ComponentTemplates-LibraryNamespaces">Library Namespaces</h2><p>If you are
using many components from a common Tapestry component library, you can use a
special namespace to simplify references to those components.</p><p>The special
namespace URI <code>tapestry-library:path</code> can be defined; the path is a
prefix used in conjunction with component element names.</p><p>Borrowing from
the above example, all of the following are equivalent:</
p><parameter ac:name="language">xml</parameter><plain-text-body><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:a="tapestry-library:ajax">
+</pre>
+</div></div><p>In this example, the <t:form> component's body contains
the other components. Structurally, all of these components (the Form, Errors,
Label, etc.) are peers: children of the page. They are all <em>embedded</em>
within the page. The Errors, Label, TextField and so forth are
<em>enclosed</em> within the Form's body ... meaning that the Form controls if,
when, and under what circumstances those components will render.</p><p>In some
cases, components require some kind of enclosure; for example, all of the field
control components (such as TextField) will throw a runtime exception if not
enclosed by a Form component.</p><p>It is possible to place Tapestry components
in sub-packages. For example, your application may have a package
org.example.myapp.components.ajax.Dialog. This component's normal type name is
"ajax/dialog" (because it is in the ajax sub-folder). This name is problematic,
as it is not valid to define an XML element with an element name <code><t:aja
x/dialog></code>. Instead, just replace the slashes with periods:
<code><t:ajax.dialog></code>. Library namespaces (described in the next
section) are a preferred way of handling components in sub-folders.</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>When using a component library,
the library will map its components to a <em>virtual sub-folder</em> of the
application. The same naming mechanism works whether its is a real sub-folder
or a component library sub-folder.</p></div></div><p><span
class="confluence-anchor-link"
id="ComponentTemplates-LibraryNamespaces"></span></p><h2
id="ComponentTemplates-LibraryNamespaces">Library Namespaces</h2><p>If you are
using many components from a common Tapestry component library, you can use a
special namespace to simplify references to those component
s.</p><p>The special namespace URI <code>tapestry-library:path</code> can be
defined; the path is a prefix used in conjunction with component element
names.</p><p>Borrowing from the above example, all of the following are
equivalent:</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;"><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:a="tapestry-library:ajax">
<t:ajax.dialog/>
@@ -149,34 +276,46 @@
<a:dialog/>
. . .
-</plain-text-body><p>In other words, the virtual folder, <code>ajax</code>,
defined in the namespace URI takes the place of the path prefixes
<code>ajax.</code> seen in the first element, or <code>ajax/</code> seen in the
second. As far as Tapestry is concerned, they are all equivalent.</p><h2
id="ComponentTemplates-InvisibleInstrumentation">Invisible
Instrumentation</h2><p>A favorite feature of Tapestry is <em>invisible
instrumentation</em>, the ability to mark ordinary HTML elements as components.
Invisible instrumentation leads to more concise templates that are also more
readable.</p><p>Invisible instrumentation involves using <em>namespaced</em> id
or type attributes to mark an ordinary (X)HTML element as a component. For
example:</p><parameter
ac:name="language">xml</parameter><plain-text-body><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+</pre>
+</div></div><p>In other words, the virtual folder, <code>ajax</code>, defined
in the namespace URI takes the place of the path prefixes <code>ajax.</code>
seen in the first element, or <code>ajax/</code> seen in the second. As far as
Tapestry is concerned, they are all equivalent.</p><h2
id="ComponentTemplates-InvisibleInstrumentation">Invisible
Instrumentation</h2><p>A favorite feature of Tapestry is <em>invisible
instrumentation</em>, the ability to mark ordinary HTML elements as components.
Invisible instrumentation leads to more concise templates that are also more
readable.</p><p>Invisible instrumentation involves using <em>namespaced</em> id
or type attributes to mark an ordinary (X)HTML element as a component. For
example:</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;"><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<p>
Merry Christmas:
<span t:type="Count" end="3">
Ho!
</span>
</p>
-</plain-text-body><p>The t:type attribute above marks the span element as a
component of type Count. When rendered, the span element will be
<em>replaced</em> by the output of the Count component.</p><p>The id, type and
mixins attributes must be placed in the Tapestry namespace (almost always as
t:id, t:type, and t:mixins). Any additional attributes may be in either the
Tapestry namespace or the default namespace. Placing an attribute in the
Tapestry namespace is useful when the attribute is not defined for the element
being instrumented.</p><p>An invisibly-instrumented component must still have a
type, identified in one of two ways:</p><ul><li>via the t:type attribute in the
containing template, as in the above example, or</li><li>within the containing
component's Java class using the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Component.html">Component</a>
annotation (and using the t:id attribute on the element in the
template). The Component annotation is attached to a field; the type of the
component is determined by either the type of the field or the type attribute
of the Component annotation.</li></ul><p>In <em>most</em> cases, it is merely
an aesthetic choice whether to use invisible instrumentation in your templates.
However, in a very few cases the behavior of the component is influenced by
your choice. For example, when your template includes the Loop component using
the invisible instrumentation approach, the original tag (and its informal
parameters) will render repeatedly around the body of the component. Thus, for
example:</p><parameter ac:name="language">xml</parameter><plain-text-body>
<table>
+</pre>
+</div></div><p>The t:type attribute above marks the span element as a
component of type Count. When rendered, the span element will be
<em>replaced</em> by the output of the Count component.</p><p>The id, type and
mixins attributes must be placed in the Tapestry namespace (almost always as
t:id, t:type, and t:mixins). Any additional attributes may be in either the
Tapestry namespace or the default namespace. Placing an attribute in the
Tapestry namespace is useful when the attribute is not defined for the element
being instrumented.</p><p>An invisibly-instrumented component must still have a
type, identified in one of two ways:</p><ul><li>via the t:type attribute in the
containing template, as in the above example, or</li><li>within the containing
component's Java class using the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Component.html">Component</a>
annotation (and using the t:id attribute on the element in the templ
ate). The Component annotation is attached to a field; the type of the
component is determined by either the type of the field or the type attribute
of the Component annotation.</li></ul><p>In <em>most</em> cases, it is merely
an aesthetic choice whether to use invisible instrumentation in your templates.
However, in a very few cases the behavior of the component is influenced by
your choice. For example, when your template includes the Loop component using
the invisible instrumentation approach, the original tag (and its informal
parameters) will render repeatedly around the body of the component. Thus, for
example:</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;"> <table>
<tr t:type="loop" source="items" value="item" class="prop:rowClass">
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.quantity}</td>
</tr>
</tabel>
-</plain-text-body><p>Here, the loop component "merges into" the <tr>
element. It will render out a <tr> for each <code>item</code> in the
<code>items</code> list, with each <tr> including three <td>
elements. It will also write a dynamic "class" attribute into each
<tr>.</p><p><parameter ac:name="">parameter-namespaces</parameter></p><h2
id="ComponentTemplates-ParameterNamespaces">Parameter Namespaces</h2><p>Main
Article: <a href="component-parameters.html">Component
Parameters</a></p><p>Parameter namespaces (introduced in Tapestry 5.1) are a
concise way of passing parameter blocks to components.</p><p>You must define a
special namespace, usually with the prefix "p":</p><parameter
ac:name="language">xml</parameter><plain-text-body><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:p="tapestry:parameter">
+</pre>
+</div></div><p>Here, the loop component "merges into" the <tr> element.
It will render out a <tr> for each <code>item</code> in the
<code>items</code> list, with each <tr> including three <td>
elements. It will also write a dynamic "class" attribute into each
<tr>.</p><p><span class="confluence-anchor-link"
id="ComponentTemplates-parameter-namespaces"></span></p><h2
id="ComponentTemplates-ParameterNamespaces">Parameter Namespaces</h2><p>Main
Article: <a href="component-parameters.html">Component
Parameters</a></p><p>Parameter namespaces (introduced in Tapestry 5.1) are a
concise way of passing parameter blocks to components.</p><p>You must define a
special namespace, usually with the prefix "p":</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;"><html
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
xmlns:p="tapestry:parameter">
. . .
-</plain-text-body><p>With the "tapestry:parameter" namespace defined, you can
pass block using the "p:" prefix and an element name that matches the parameter
name:</p><parameter ac:name="language">xml</parameter><plain-text-body><t:if
test="loggedIn">
+</pre>
+</div></div><p>With the "tapestry:parameter" namespace defined, you can pass
block using the "p:" prefix and an element name that matches the parameter
name:</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:if test="loggedIn">
Hello, ${userName}!
<p:else>
Click <a t:type="actionlink" t:id="login">here</a> to log in.
</p:else>
</t:if>
-</plain-text-body><p>This example passes a block of the template (containing
the ActionLink component and some text) to the If component as parameter
<code>else</code>. In the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/If.html">If
component's reference page</a> you'll see that <code>else</code> is parameter
of type <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Block.html">Block</a>.</p><p>Name-spaced
parameter elements are not allowed to have any attributes. The element name
itself is used to identify the parameter of the component to bind.</p><h2
id="ComponentTemplates-WhitespaceinTemplates">Whitespace in
Templates</h2><p>Tapestry strips out unnecessary whitespace from templates as
they are parsed. Inside any block of text, repeated whitespace is reduced to a
single space character. Blocks of text that are entirely whitespace, such a
line break and whitespace be
tween two tags, is eliminated entirely.</p><p>If you do a view source on the
rendered output, you'll see that the bulk of the rendered page is one long
unbroken line.</p><p>This approach has certain efficiency advantages on both
the server (less processing to render the page) and on the client (fewer
characters to parse). Tools such as <a class="external-link"
href="http://www.getfirebug.com/" rel="nofollow">FireBug</a> and <a
class="external-link" href="http://code.google.com/chrome/devtools/"
rel="nofollow">Chrome Developer Tools</a> are useful for allowing you to view
the rendered HTML on the client properly.</p><p>In rare cases, the whitespace
in a template <em>is</em> significant. Perhaps you are creating a <pre>
(preformatted) block of text, or the whitespace interacts with your stylesheet
to some desired effect.</p><p>You may use the standard XML attribute
<code>xml:space</code> to indicate to Tapestry whether whitespace should be
compressed (<code>xml:space="default"
</code>) or preserved (<code>xml:space="preserve"</code>). Such attributes are
stripped out by the template parser; they do not appear in the rendered
output.</p><p>The xml: namespace prefix is built into all XML documents, there
is no special configuration (as there is with the Tapestry
namespace).</p><p>For example:</p><parameter
ac:name="language">xml</parameter><plain-text-body> <ul class="navmenu"
xml:space="preserve">
+</pre>
+</div></div><p>This example passes a block of the template (containing the
ActionLink component and some text) to the If component as parameter
<code>else</code>. In the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/If.html">If
component's reference page</a> you'll see that <code>else</code> is parameter
of type <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Block.html">Block</a>.</p><p>Name-spaced
parameter elements are not allowed to have any attributes. The element name
itself is used to identify the parameter of the component to bind.</p><h2
id="ComponentTemplates-WhitespaceinTemplates">Whitespace in
Templates</h2><p>Tapestry strips out unnecessary whitespace from templates as
they are parsed. Inside any block of text, repeated whitespace is reduced to a
single space character. Blocks of text that are entirely whitespace, such a
line break and whitespace between
two tags, is eliminated entirely.</p><p>If you do a view source on the
rendered output, you'll see that the bulk of the rendered page is one long
unbroken line.</p><p>This approach has certain efficiency advantages on both
the server (less processing to render the page) and on the client (fewer
characters to parse). Tools such as <a class="external-link"
href="http://www.getfirebug.com/" rel="nofollow">FireBug</a> and <a
class="external-link" href="http://code.google.com/chrome/devtools/"
rel="nofollow">Chrome Developer Tools</a> are useful for allowing you to view
the rendered HTML on the client properly.</p><p>In rare cases, the whitespace
in a template <em>is</em> significant. Perhaps you are creating a <pre>
(preformatted) block of text, or the whitespace interacts with your stylesheet
to some desired effect.</p><p>You may use the standard XML attribute
<code>xml:space</code> to indicate to Tapestry whether whitespace should be
compressed (<code>xml:space="default"</code
>) or preserved (<code>xml:space="preserve"</code>). Such attributes are
>stripped out by the template parser; they do not appear in the rendered
>output.</p><p>The xml: namespace prefix is built into all XML documents,
>there is no special configuration (as there is with the Tapestry
>namespace).</p><p>For example:</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;"> <ul class="navmenu" xml:space="preserve">
<li t:type="loop" t:source="pages" t:value="var:page">
<t:pagelink page="var:page">${var:page}</t:pagelink>
</li>
</ul>
-</plain-text-body><p>This will preserve the whitespace between the <ul>
and <li> elements, and between the (rendered) <li> elements and the
nested <a> elements. For example, the output may look something
like:</p><parameter ac:name="language">xml</parameter><plain-text-body>
<ul>
+</pre>
+</div></div><p>This will preserve the whitespace between the <ul> and
<li> elements, and between the (rendered) <li> elements and the
nested <a> elements. For example, the output may look something
like:</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;"> <ul>
<li>
<a href="showcart>ShowCart</a>
</li>
@@ -184,17 +323,24 @@
<a href="viewaccount">ViewAccount</a>
</li>
</ul>
-</plain-text-body><p>With normal whitespace compression, you would see the
following rendered output:</p><parameter
ac:name="language">xml</parameter><plain-text-body> <ul><li><a
href="showcart">ShowCart</a></li><li><a
href="viewaccount">ViewAccount</li></ul>
-</plain-text-body><p>You can even put further <code>xml:space</code>
attributes inside nested elements to fine-tune the control over what whitespace
is preserved and what is compressed.</p><h2
id="ComponentTemplates-TemplateInheritance">Template Inheritance</h2><p>If a
component does not have a template, but extends from a component class that
does have a template, then the parent class' template will be used by the child
component.</p><p>This allows a component to extend from a base class but not
have to duplicate the base class' template.</p><p>Tapestry 5.1 adds a
significant new feature: template inheritance with <em>extension points</em>.
Previously, a component which extended another component had to inherit the
parent component's entire template, or copy-and-paste the
template.</p><p>Parent template can now mark replaceable sections as
<t:extension-point>s, and sub-components can extend the parent template
and <t:replace> those sections.</p><p>This can work across
multiple levels of inheritance.</p><rich-text-body><p>Overuse of this feature
is <em>not recommended</em>: in general use of composition, rather than
inheritance, will be easier to understand and maintain. There are certain
specific cases where overrides will allow a for much wider and easier reuse of
a component, but the component needs to be carefully designed to support this
kind of inheritance properly.</p></rich-text-body><h3
id="ComponentTemplates-<t:extension-point>"><t:extension-point></h3><p>Marks
a point in a template that may be replaced. A unique id (case insensitive) is
used in the template and its sub-templates to link extension points to possible
overrides.</p><parameter ac:name="language">xml</parameter><plain-text-body>
<t:extension-point id="title">
+</pre>
+</div></div><p>With normal whitespace compression, you would see the following
rendered output:</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;"> <ul><li><a
href="showcart">ShowCart</a></li><li><a
href="viewaccount">ViewAccount</li></ul>
+</pre>
+</div></div><p>You can even put further <code>xml:space</code> attributes
inside nested elements to fine-tune the control over what whitespace is
preserved and what is compressed.</p><h2
id="ComponentTemplates-TemplateInheritance">Template Inheritance</h2><p>If a
component does not have a template, but extends from a component class that
does have a template, then the parent class' template will be used by the child
component.</p><p>This allows a component to extend from a base class but not
have to duplicate the base class' template.</p><p>Tapestry 5.1 adds a
significant new feature: template inheritance with <em>extension points</em>.
Previously, a component which extended another component had to inherit the
parent component's entire template, or copy-and-paste the
template.</p><p>Parent template can now mark replaceable sections as
<t:extension-point>s, and sub-components can extend the parent template
and <t:replace> those sections.</p><p>This can work across multip
le levels of inheritance.</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>Overuse of this feature is <em>not
recommended</em>: in general use of composition, rather than inheritance, will
be easier to understand and maintain. There are certain specific cases where
overrides will allow a for much wider and easier reuse of a component, but the
component needs to be carefully designed to support this kind of inheritance
properly.</p></div></div><h3
id="ComponentTemplates-<t:extension-point>"><t:extension-point></h3><p>Marks
a point in a template that may be replaced. A unique id (case insensitive) is
used in the template and its sub-templates to link extension points to possible
overrides.</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:extension-point id="title">
<h1>${defaultTitle}</h1>
</t:extension-point>
-</plain-text-body><h3
id="ComponentTemplates-<t:extend>"><t:extend></h3><p>Root element
of a child template that extends from its parent template. The <t:extend>
attribute may only appear as the root element and may only contain
<t:replace> elements.</p><h3
id="ComponentTemplates-<t:replace>"><t:replace></h3><p>Replaces an
extension point from a parent template. <t:replace> may only appear as
the immediate child of a root <t:extend> element.</p><parameter
ac:name="language">xml</parameter><plain-text-body><t:extend
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+</pre>
+</div></div><h3
id="ComponentTemplates-<t:extend>"><t:extend></h3><p>Root element
of a child template that extends from its parent template. The <t:extend>
attribute may only appear as the root element and may only contain
<t:replace> elements.</p><h3
id="ComponentTemplates-<t:replace>"><t:replace></h3><p>Replaces an
extension point from a parent template. <t:replace> may only appear as
the immediate child of a root <t:extend> element.</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:extend
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<t:replace id="title">
<h1><img src="${context:images/icon.jpg}"/>
Customer Service</h1>
</t:replace>
</t:extend>
-</plain-text-body></div>
+</pre>
+</div></div></div>
</div>
<div class="clearer"></div>