Modified: websites/production/tapestry/content/tapestry-tutorial.html
==============================================================================
--- websites/production/tapestry/content/tapestry-tutorial.html (original)
+++ websites/production/tapestry/content/tapestry-tutorial.html Wed Sep 20
12:29:16 2017
@@ -36,26 +36,13 @@
<div class="wrapper bs">
- <div id="navigation"><div class="nav"><ul class="alternate"><li><a
href="index.html">Home</a></li><li><a href="getting-started.html">Getting
Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a
href="download.html">Download</a></li><li><a
href="about.html">About</a></li><li><a class="external-link"
href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a
href="community.html">Community</a></li><li><a class="external-link"
href="http://www.apache.org/security/">Security</a></li><li><a
class="external-link" href="http://www.apache.org/">Apache</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div>
-
-</div>
+ <div id="navigation"><div class="nav"><ul class="alternate"><li><a
href="index.html">Home</a></li><li><a href="getting-started.html">Getting
Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a
href="download.html">Download</a></li><li><a
href="about.html">About</a></li><li><a class="external-link"
href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a
href="community.html">Community</a></li><li><a class="external-link"
href="http://www.apache.org/security/">Security</a></li><li><a
class="external-link" href="http://www.apache.org/">Apache</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div></div>
<div id="top">
- <div id="smallbanner"><div class="searchbox"
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999;
font-size: 90%">Tapestry docs, issues, wikis & blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get"
action="http://tapestry.apache.org/search.html">
- <input type="text" name="q">
- <input type="submit" value="Search">
-</form>
-
-</div>
-
-
-<div class="emblem" style="float:left"><p><a href="index.html"><span
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image
confluence-external-resource"
src="http://tapestry.apache.org/images/tapestry_small.png"
data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div>
-
-
-<div class="title" style="float:left; margin: 0 0 0 3em"><h1
id="SmallBanner-PageTitle">Tapestry Tutorial</h1></div>
-
-</div>
+ <div id="smallbanner"><div class="searchbox"
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999;
font-size: 90%">Tapestry docs, issues, wikis & blogs:</span><form
enctype="application/x-www-form-urlencoded" method="get"
action="http://tapestry.apache.org/search.html">
+ <input type="text" name="q">
+ <input type="submit" value="Search">
+</form></div><div class="emblem" style="float:left"><p><a
href="index.html"><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image confluence-external-resource"
src="http://tapestry.apache.org/images/tapestry_small.png"
data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div
class="title" style="float:left; margin: 0 0 0 3em"><h1
id="SmallBanner-PageTitle">Tapestry Tutorial</h1></div></div>
<div class="clearer"></div>
</div>
@@ -67,7 +54,37 @@
</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 = "new-users" and space =
currentSpace()</parameter></rich-text-body><h1
id="TapestryTutorial-TableofContents">Table of Contents</h1><p></p><h1
id="TapestryTutorial-Introduction">Introduction</h1><p>Welcome to
Tapestry!</p><p>This is a tutorial for people who will be creating Tapestry web
applications. It doesn't matter whether you have experience with earlier
versions of Tapestry or other web frameworks. In fact, in some ways, the less
you know about web development in general, the better off you may be ... that
much less to unlearn!</p><p>You do need to have a reasonable understanding of
HTML
, a smattering of XML, and a good understanding of basic Java language
features, including Annotations.</p><h1
id="TapestryTutorial-TheChallengesofWebApplicationDevelopment">The Challenges
of Web Application Development</h1><p>If you're used to developing web
applications using servlets and JSPs, or with Struts, you are simply used to a
lot of pain. So much pain, you may not even understand the dire situation you
are in! These are environments with no safety net; Struts and the Servlet API
have no idea how your application is structured, or how the different pieces
fit together. Any URL can be an action and any action can forward to any view
(usually a JSP) to provide an HTML response to the web browser. The pain is the
unending series of small, yet important, decisions you have to make as a
developer (and communicate to the rest of your team). What are the naming
conventions for actions, for pages, for attributes stored in the HttpSession or
HttpServletRequest? Where do cross-cutti
ng concerns such as database transactions, caching and security get
implemented (and do you have to cut-and-paste Java or XML to make it work?) How
are your packages organized ... where to the user interface classes go, and
where do the data and entity objects go? How do you share code from one part of
your application to another?</p><p>On top of all that, the traditional
approaches thrust something most unwanted in your face: <em>multi-threaded
coding</em>. Remember back to Object Oriented Programming 101 where an object
was defined as a bundle of data and operations on that data? You have to
unlearn that lesson as soon as you build a traditional web application, because
web applications are multi-threaded. An application server could be handling
dozens or hundreds of requests from individual users, each in their own thread,
and each sharing the exact same objects. Suddenly, you can't store data inside
an object (a servlet or a Struts Action) because whatever data you store for one
user will be instantly overwritten by some other user.</p><p>Worse, your
objects each have only one operation: <code>doGet()</code> or
<code>doPost()</code>.</p><p>Meanwhile, most of your day-to-day work involves
deciding how to package up some data already inside a particular Java object
and squeeze that data into a URL's query parameters, so that you can write more
code to convert it back if the user clicks that particular link. And don't
forget editing a bunch of XML files to keep the servlet container, or the
Struts framework, aware of these decisions.</p><p>Just for laughs, remember
that you have to rebuild, redeploy and restart your application after virtually
any change. Is any of this familiar? Then perhaps you'd appreciate something a
little <em>less</em> familiar: Tapestry.</p><h1
id="TapestryTutorial-TheTapestryWay">The Tapestry Way</h1><p>Tapestry uses a
very different model: a structured, organized world of pages, and components
within pages. Everything has a very spec
ific name (that you provide). Once you know the name of a page, you know the
location of the Java class for that page, the location of the template for that
page, and the total structure of the page. Tapestry knows all this as well, and
can make things <strong>just work</strong>.</p><p>As we'll see in the following
pages, Tapestry lets you code in terms of your objects. You'll barely see any
Tapestry classes, outside of a few Java annotations. If you have information to
store, store it as fields of your classes, not inside the HttpServletRequest or
HttpSession. If you need some code to execute, it's just a simple annotation or
method naming convention to get Tapestry to invoke that method, at the right
time, with the right data. The methods don't even have to be
public!</p><p>Tapestry also shields you from most of the multi-threaded aspects
of web application development. Tapestry manages the life cycle of your page
and components objects, and the fields of the pages and components,
in a thread-safe way. Your page and component classes always look like
simple, standard <a class="external-link"
href="http://en.wikipedia.org/wiki/Plain_Old_Java_Object"
rel="nofollow">POJOs</a>.</p><p>Tapestry began in January 2000, and it now
reflects over fifteen years of experience of the entire Tapestry community.
Tapestry brings to the table all that experience about the best ways to build
scalable, maintainable, robust, internationalized, and Ajax-enabled
applications. Tapestry 5 represents a completely new code base (compared to
Tapestry 4) designed to simplify the Tapestry coding model while at the same
time extending the power of Tapestry and improving performance.</p><h1
id="TapestryTutorial-GettingtheTutorialSource">Getting the Tutorial
Source</h1><p>Although you won't need it, the source code for this tutorial is
available on <a class="external-link"
href="https://github.com/hlship/tapestry5-tutorial"
rel="nofollow">GitHub</a>.</p><h1 id="TapestryTutorial-TimetoBegi
n">Time to Begin</h1><p>Okay, enough background. Now let's get started on the
tutorial: <a href="dependencies-tools-and-plugins.html">Dependencies, Tools
and Plugins</a></p><p> </p></div>
+ <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="tapestry-for-jsf-users.html">Tapestry for JSF Users</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="tapestry-tutorial.html">Tapestry Tutorial</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="principles.html">Principles</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="getting-started.html">Getting Started</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="introduction.html">Introduction</a>
+ </div> </li></ul></div><h1 id="TapestryTutorial-TableofContents">Table of
Contents</h1><p></p><ul class="childpages-macro"><li><a
href="dependencies-tools-and-plugins.html">Dependencies, Tools and
Plugins</a></li><li><a href="creating-the-skeleton-application.html">Creating
The Skeleton Application</a></li><li><a
href="exploring-the-project.html">Exploring the Project</a></li><li><a
href="implementing-the-hi-lo-guessing-game.html">Implementing the Hi-Lo
Guessing Game</a></li><li><a
href="using-beaneditform-to-create-user-forms.html">Using BeanEditForm To
Create User Forms</a></li><li><a
href="using-tapestry-with-hibernate.html">Using Tapestry With
Hibernate</a></li></ul><h1
id="TapestryTutorial-Introduction">Introduction</h1><p>Welcome to
Tapestry!</p><p>This is a tutorial for people who will be creating Tapestry web
applications. It doesn't matter whether you have experience with earlier
versions of Tapestry or other web frameworks. In fact, in some ways, the less
you know
about web development in general, the better off you may be ... that much less
to unlearn!</p><p>You do need to have a reasonable understanding of HTML, a
smattering of XML, and a good understanding of basic Java language features,
including Annotations.</p><h1
id="TapestryTutorial-TheChallengesofWebApplicationDevelopment">The Challenges
of Web Application Development</h1><p>If you're used to developing web
applications using servlets and JSPs, or with Struts, you are simply used to a
lot of pain. So much pain, you may not even understand the dire situation you
are in! These are environments with no safety net; Struts and the Servlet API
have no idea how your application is structured, or how the different pieces
fit together. Any URL can be an action and any action can forward to any view
(usually a JSP) to provide an HTML response to the web browser. The pain is the
unending series of small, yet important, decisions you have to make as a
developer (and communicate to the rest of y
our team). What are the naming conventions for actions, for pages, for
attributes stored in the HttpSession or HttpServletRequest? Where do
cross-cutting concerns such as database transactions, caching and security get
implemented (and do you have to cut-and-paste Java or XML to make it work?) How
are your packages organized ... where to the user interface classes go, and
where do the data and entity objects go? How do you share code from one part of
your application to another?</p><p>On top of all that, the traditional
approaches thrust something most unwanted in your face: <em>multi-threaded
coding</em>. Remember back to Object Oriented Programming 101 where an object
was defined as a bundle of data and operations on that data? You have to
unlearn that lesson as soon as you build a traditional web application, because
web applications are multi-threaded. An application server could be handling
dozens or hundreds of requests from individual users, each in their own thread,
and each
sharing the exact same objects. Suddenly, you can't store data inside an
object (a servlet or a Struts Action) because whatever data you store for one
user will be instantly overwritten by some other user.</p><p>Worse, your
objects each have only one operation: <code>doGet()</code> or
<code>doPost()</code>.</p><p>Meanwhile, most of your day-to-day work involves
deciding how to package up some data already inside a particular Java object
and squeeze that data into a URL's query parameters, so that you can write more
code to convert it back if the user clicks that particular link. And don't
forget editing a bunch of XML files to keep the servlet container, or the
Struts framework, aware of these decisions.</p><p>Just for laughs, remember
that you have to rebuild, redeploy and restart your application after virtually
any change. Is any of this familiar? Then perhaps you'd appreciate something a
little <em>less</em> familiar: Tapestry.</p><h1
id="TapestryTutorial-TheTapestryWay">The Ta
pestry Way</h1><p>Tapestry uses a very different model: a structured,
organized world of pages, and components within pages. Everything has a very
specific name (that you provide). Once you know the name of a page, you know
the location of the Java class for that page, the location of the template for
that page, and the total structure of the page. Tapestry knows all this as
well, and can make things <strong>just work</strong>.</p><p>As we'll see in the
following pages, Tapestry lets you code in terms of your objects. You'll barely
see any Tapestry classes, outside of a few Java annotations. If you have
information to store, store it as fields of your classes, not inside the
HttpServletRequest or HttpSession. If you need some code to execute, it's just
a simple annotation or method naming convention to get Tapestry to invoke that
method, at the right time, with the right data. The methods don't even have to
be public!</p><p>Tapestry also shields you from most of the multi-threaded a
spects of web application development. Tapestry manages the life cycle of your
page and components objects, and the fields of the pages and components, in a
thread-safe way. Your page and component classes always look like simple,
standard <a class="external-link"
href="http://en.wikipedia.org/wiki/Plain_Old_Java_Object"
rel="nofollow">POJOs</a>.</p><p>Tapestry began in January 2000, and it now
reflects over fifteen years of experience of the entire Tapestry community.
Tapestry brings to the table all that experience about the best ways to build
scalable, maintainable, robust, internationalized, and Ajax-enabled
applications. Tapestry 5 represents a completely new code base (compared to
Tapestry 4) designed to simplify the Tapestry coding model while at the same
time extending the power of Tapestry and improving performance.</p><h1
id="TapestryTutorial-GettingtheTutorialSource">Getting the Tutorial
Source</h1><p>Although you won't need it, the source code for this tutorial is
avail
able on <a class="external-link"
href="https://github.com/hlship/tapestry5-tutorial"
rel="nofollow">GitHub</a>.</p><h1 id="TapestryTutorial-TimetoBegin">Time to
Begin</h1><p>Okay, enough background. Now let's get started on the tutorial: <a
href="dependencies-tools-and-plugins.html">Dependencies, Tools and
Plugins</a></p><p> </p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/templating-and-markup-faq.html
==============================================================================
--- websites/production/tapestry/content/templating-and-markup-faq.html
(original)
+++ websites/production/tapestry/content/templating-and-markup-faq.html 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,29 +77,52 @@
</div>
<div id="content">
- <div
id="ConfluenceContent"><plain-text-body>{scrollbar}</plain-text-body><h2
id="TemplatingandMarkupFAQ-TemplatingandMarkup">Templating and
Markup</h2><p>Main Article: <a href="component-templates.html">Component
Templates</a></p><h3
id="TemplatingandMarkupFAQ-WhydoIgetaSAXParseExceptionwhenIuseanHTMLentity,suchas&nbsp;inmytemplate?">Why
do I get a SAXParseException when I use an HTML entity, such as
<code>&nbsp;</code> in my template?</h3><p>Tapestry uses a standard SAX
parser to read your templates. This means that your templates must be <em>well
formed</em>: open and close tags must balance, attribute values must be quoted,
and entities must be declared. The easiest way to accomplish this is to add a
DOCTYPE to your the top of your template:</p><parameter
ac:name="controls">true</parameter><parameter
ac:name="language">xml</parameter><plain-text-body><!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
+ <div id="ConfluenceContent"><h2
id="TemplatingandMarkupFAQ-TemplatingandMarkup">Templating and
Markup</h2><p>Main Article: <a href="component-templates.html">Component
Templates</a></p><h3
id="TemplatingandMarkupFAQ-WhydoIgetaSAXParseExceptionwhenIuseanHTMLentity,suchas&nbsp;inmytemplate?">Why
do I get a SAXParseException when I use an HTML entity, such as
<code>&nbsp;</code> in my template?</h3><p>Tapestry uses a standard SAX
parser to read your templates. This means that your templates must be <em>well
formed</em>: open and close tags must balance, attribute values must be quoted,
and entities must be declared. The easiest way to accomplish this is to add a
DOCTYPE to your the top of your template:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-</plain-text-body><p>Part of the DOCTYPE is the declaration of entities such
as <code>&nbsp;</code>.</p><p>Alternately, you can simply use the numeric
version: <code>&#160</code>; This is the exact same character and will
render identically in the browser.</p><p>Starting in release 5.3, Tapestry
introduces an XHTML doctype when no doctype is present; this means that common
HTML entities will work correctly.</p><h3
id="TemplatingandMarkupFAQ-Whydosomeimagesinmypageshowupasbrokenlinks?">Why do
some images in my page show up as broken links?</h3><p>You have to be careful
when using relative URLs inside page templates; the base URL may not always be
what you expect. For example, inside your <code>ViewUser.tml</code> file, you
may have:</p><parameter ac:name="controls">true</parameter><parameter
ac:name="language">xml</parameter><plain-text-body> <img class="icon"
src="icons/admin.png"/>${user.name} has Administrative access
-</plain-text-body><p>This makes sense; ViewUser.tml is in the web context, as
is the icons folder. The default URL for this page will be /viewuser (assuming
that ViewUser class is in the  <em>root-package</em>.pages
package).</p><p>However, the ViewUser page might use a page activation context
to identify which user is to be displayed:</p><parameter
ac:name="controls">true</parameter><parameter
ac:name="language">java</parameter><plain-text-body>public class ViewUser
+</pre>
+</div></div><p>Part of the DOCTYPE is the declaration of entities such as
<code>&nbsp;</code>.</p><p>Alternately, you can simply use the numeric
version: <code>&#160</code>; This is the exact same character and will
render identically in the browser.</p><p>Starting in release 5.3, Tapestry
introduces an XHTML doctype when no doctype is present; this means that common
HTML entities will work correctly.</p><h3
id="TemplatingandMarkupFAQ-Whydosomeimagesinmypageshowupasbrokenlinks?">Why do
some images in my page show up as broken links?</h3><p>You have to be careful
when using relative URLs inside page templates; the base URL may not always be
what you expect. For example, inside your <code>ViewUser.tml</code> file, you
may have:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <img class="icon"
src="icons/admin.png"/>${user.name} has Administrative access
+</pre>
+</div></div><p>This makes sense; ViewUser.tml is in the web context, as is the
icons folder. The default URL for this page will be /viewuser (assuming that
ViewUser class is in the  <em>root-package</em>.pages
package).</p><p>However, the ViewUser page might use a page activation context
to identify which user is to be displayed:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class ViewUser
@Property
@PageActivationContext
private User user;
. . .
-</plain-text-body><p>With a page activation context, the URL for the page will
incorporate the ID of the User object, something like
<code>/viewuser/37371</code>. This is why the relative URL to the
<code>admin.png</code> image is broken: the base path is relative to the page's
URL, not to the page template. (In fact, the page template may not even be in
the web context, it may be stored on the classpath, as component templates
are.)</p><p>One solution would be to predict what the page URL will be, and
adjust the path for that:</p><parameter
ac:name="controls">true</parameter><parameter
ac:name="language">xml</parameter><plain-text-body> <img class="icon"
src="../icons/admin.png"/>${user.name} has Administrative access
-</plain-text-body><p>But this has its own problems; the page activation
context may vary in length at different times, or the template in question may
be a component used across many different pages, making it difficult to predict
what the correct relative URL would be.</p><p>The <em>best</em> solution for
this situation, one that will be sure to work in all pages and all components,
is to make use of the <code>context:</code> binding prefix:</p><parameter
ac:name="controls">true</parameter><parameter
ac:name="language">xml</parameter><plain-text-body> <img class="icon"
src="${context:icons/admin.png}"/>${user.name} has Administrative access
-</plain-text-body><p>The src attribute of the <img> tag will now be
bound to a dynamically computed value: the location of the image file relative
to the web application context. This is especially important for components
that may be used on different pages.</p><h3
id="TemplatingandMarkupFAQ-What'sthedifferencebetweenidandt:id?">What's the
difference between <code>id</code> and <code>t:id</code>?</h3><p>You might
occasionally see something like the following in a template:</p><parameter
ac:name="controls">true</parameter><parameter
ac:name="language">xml</parameter><plain-text-body><t:zone id="status"
t:id="statusZone">
-</plain-text-body><p>Why two ids? Why are they different?</p><p>The
<code>t:id</code> attribute is the Tapestry component id. This id is unique
within its immediate container. This is the id you might use to inject the
component into your page class:</p><parameter
ac:name="controls">true</parameter><parameter
ac:name="language">java</parameter><plain-text-body> @InjectComponent
+</pre>
+</div></div><p>With a page activation context, the URL for the page will
incorporate the ID of the User object, something like
<code>/viewuser/37371</code>. This is why the relative URL to the
<code>admin.png</code> image is broken: the base path is relative to the page's
URL, not to the page template. (In fact, the page template may not even be in
the web context, it may be stored on the classpath, as component templates
are.)</p><p>One solution would be to predict what the page URL will be, and
adjust the path for that:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <img class="icon"
src="../icons/admin.png"/>${user.name} has Administrative access
+</pre>
+</div></div><p>But this has its own problems; the page activation context may
vary in length at different times, or the template in question may be a
component used across many different pages, making it difficult to predict what
the correct relative URL would be.</p><p>The <em>best</em> solution for this
situation, one that will be sure to work in all pages and all components, is to
make use of the <code>context:</code> binding prefix:</p><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <img class="icon"
src="${context:icons/admin.png}"/>${user.name} has Administrative access
+</pre>
+</div></div><p>The src attribute of the <img> tag will now be bound to a
dynamically computed value: the location of the image file relative to the web
application context. This is especially important for components that may be
used on different pages.</p><h3
id="TemplatingandMarkupFAQ-What'sthedifferencebetweenidandt:id?">What's the
difference between <code>id</code> and <code>t:id</code>?</h3><p>You might
occasionally see something like the following in a template:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"><t:zone id="status" t:id="statusZone">
+</pre>
+</div></div><p>Why two ids? Why are they different?</p><p>The
<code>t:id</code> attribute is the Tapestry component id. This id is unique
within its immediate container. This is the id you might use to inject the
component into your page class:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> @InjectComponent
private Zone statusZone;
-</plain-text-body><p>The other id is the client id, a unique id for the
rendered element within the client-side DOM. JavaScript that needs to access
the element uses this id. For example:</p><parameter
ac:name="controls">true</parameter><parameter
ac:name="language">text</parameter><plain-text-body> $('status').hide();
-</plain-text-body><p>In many components, the <code>id</code> attribute is an
informal parameter; a value from the template that is blindly echoed into the
output document. In other cases, the component itself has an <code>id</code>
attribute. Often, in the latter case, the Tapestry component id is the
<em>default</em> value for the client id.</p><h3
id="TemplatingandMarkupFAQ-WhydomyimagesandstylesheetsendupwithaweirdURLslike/assets/meta/zeea17aee26bc0cae/layout/layout.css?">Why
do my images and stylesheets end up with a weird URLs like
<code>/assets/meta/zeea17aee26bc0cae/layout/layout.css</code>?</h3><p>Tapestry
doesn't rely on the servlet container to serve up your static assets (images,
stylesheets, flash movies, etc.). Instead, Tapestry processes the requests
itself, streaming assets to the browser.</p><p>Asset content will be GZIP
compressed (if the client supports compression, and the content is
compressible). In addition, Tapestry will set a far-future expires header on
the
content. This means that the browser will not ask for the file again, greatly
reducing network traffic.</p><p>The weird hex string is
a <em>fingerprint</em>; it is a hash code computed from the actual content
of the asset. If the asset ever changes, it will have a new fingerprint, and so
will be a new path and a new (immutable) resource. This approach, combined with
a far-future expires header also provided by Tapestry, ensures that clients
aggressively cache assets as they navigate your site, or even between
visits.</p><p><span style="color: rgb(83,145,38);font-size: 16.0px;line-height:
1.5625;">How do I add a CSS class to a Tapestry component?</span></p><p>As they
say, "just do it". The majority of Tapestry components support <em>informal
parameters</em>, meaning that any extra attributes in the element (in the
template) will be rendered out as additional attributes. So, you can apply a
CSS class or style quite easily:</p><parameter
ac:name="controls">true</parameter><paramet
er ac:name="language">xml</parameter><plain-text-body> <t:textfield
t:id="username" class="big-green"/>
-</plain-text-body><p>You can even use template expansions inside the attribute
value:</p><parameter ac:name="controls">true</parameter><parameter
ac:name="language">xml</parameter><plain-text-body> <t:textfield
t:id="username" class="${usernameClass}"/>
-</plain-text-body><p>and</p><parameter
ac:name="controls">true</parameter><parameter
ac:name="language">java</parameter><plain-text-body> public String
getUsernameClass()
+</pre>
+</div></div><p>The other id is the client id, a unique id for the rendered
element within the client-side DOM. JavaScript that needs to access the element
uses this id. For example:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: text; gutter: false; theme: Default"
style="font-size:12px;"> $('status').hide();
+</pre>
+</div></div><p>In many components, the <code>id</code> attribute is an
informal parameter; a value from the template that is blindly echoed into the
output document. In other cases, the component itself has an <code>id</code>
attribute. Often, in the latter case, the Tapestry component id is the
<em>default</em> value for the client id.</p><h3
id="TemplatingandMarkupFAQ-WhydomyimagesandstylesheetsendupwithaweirdURLslike/assets/meta/zeea17aee26bc0cae/layout/layout.css?">Why
do my images and stylesheets end up with a weird URLs like
<code>/assets/meta/zeea17aee26bc0cae/layout/layout.css</code>?</h3><p>Tapestry
doesn't rely on the servlet container to serve up your static assets (images,
stylesheets, flash movies, etc.). Instead, Tapestry processes the requests
itself, streaming assets to the browser.</p><p>Asset content will be GZIP
compressed (if the client supports compression, and the content is
compressible). In addition, Tapestry will set a far-future expires header on
the conten
t. This means that the browser will not ask for the file again, greatly
reducing network traffic.</p><p>The weird hex string is
a <em>fingerprint</em>; it is a hash code computed from the actual content
of the asset. If the asset ever changes, it will have a new fingerprint, and so
will be a new path and a new (immutable) resource. This approach, combined with
a far-future expires header also provided by Tapestry, ensures that clients
aggressively cache assets as they navigate your site, or even between
visits.</p><p><span style="color: rgb(83,145,38);font-size: 16.0px;line-height:
1.5625;">How do I add a CSS class to a Tapestry component?</span></p><p>As they
say, "just do it". The majority of Tapestry components support <em>informal
parameters</em>, meaning that any extra attributes in the element (in the
template) will be rendered out as additional attributes. So, you can apply a
CSS class or style quite easily:</p><div class="code panel pdl"
style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <t:textfield t:id="username" class="big-green"/>
+</pre>
+</div></div><p>You can even use template expansions inside the attribute
value:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default"
style="font-size:12px;"> <t:textfield t:id="username"
class="${usernameClass}"/>
+</pre>
+</div></div><p>and</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 String getUsernameClass()
{
return isUrgent() ? "urgent" : null;
}
-</plain-text-body><p>When an informal parameter is bound to null, then the
attribute is not written out at all.</p><p>You can verify which components
support informal parameters by checking the component reference, or looking for
the @<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SupportsInformalParameters.html">SupportsInformalParameters</a>
annotation in the components' source
file.</p><plain-text-body>{scrollbar}</plain-text-body><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p> </p><p> </p><p> </p><p> </p></div>
+</pre>
+</div></div><p>When an informal parameter is bound to null, then the attribute
is not written out at all.</p><p>You can verify which components support
informal parameters by checking the component reference, or looking for the @<a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/SupportsInformalParameters.html">SupportsInformalParameters</a>
annotation in the components' source
file.</p><p> </p><p> </p><p> </p><p> </p><p> </p><p> </p><p></p><p></p><p></p><p></p><p></p><p></p><div
class="display-footnotes"></div>
+<p></p><p></p><p></p><p></p><p></p><p> </p><p> </p><p> </p><p> </p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/test-page-2.html
==============================================================================
--- websites/production/tapestry/content/test-page-2.html (original)
+++ websites/production/tapestry/content/test-page-2.html Wed Sep 20 12:29:16
2017
@@ -67,8 +67,17 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><p><rich-text-body>
-</rich-text-body></p>
+ <div id="ConfluenceContent"><p>
+<style type="text/css">/*<![CDATA[*/
+div.rbtoc1497151227816 {padding: 0px;}
+div.rbtoc1497151227816 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1497151227816 li {margin-left: 0px;padding-left: 0px;}
+
+/*]]>*/</style></p><div class="toc-macro rbtoc1497151227816">
+<ul class="toc-indentation"><li><a href="#TestPage2-Generalquestions">General
questions</a>
+<ul class="toc-indentation"><li><a
href="#TestPage2-HowdoIgetstartedwithTapestry?">How do I get started with
Tapestry?</a></li><li><a
href="#TestPage2-WhydoesTapestryusePrototype?WhynotinsertfavoriteJavaScriptlibraryhere?">Why
does Tapestry use Prototype? Why not insert favorite JavaScript library
here?</a></li><li><a
href="#TestPage2-WhydoesTapestryhaveitsownInversionofControlContainer?WhynotSpringorGuice?">Why
does Tapestry have its own Inversion of Control Container? Why not Spring or
Guice?</a></li><li><a
href="#TestPage2-HowdoIupgradefromTapestry4toTapestry5?">How do I upgrade from
Tapestry 4 to Tapestry 5?</a></li><li><a
href="#TestPage2-WhyaretherebothRequestandHttpServletRequest?">Why are there
both Request and HttpServletRequest?</a></li></ul>
+</li></ul>
+</div>
<h2 id="TestPage2-Generalquestions">General questions</h2>
@@ -111,7 +120,8 @@
<p>However, the stronger reason for Request (and the related interfaces
Response and Session) is to enable the support for Portlets at some point in
the future. By writing code in terms of Tapestry's Request, and not
HttpServletRequest, you can be assured that the same code will operate in both
Servlet Tapestry and Portlet Tapestry.</p>
<hr>
-<p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p></div>
+<p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><div
class="display-footnotes"></div>
+<p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/test-page.html
==============================================================================
--- websites/production/tapestry/content/test-page.html (original)
+++ websites/production/tapestry/content/test-page.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"/>
@@ -70,32 +80,51 @@
<div id="ConfluenceContent"><p>Test page.</p>
<h2 id="TestPage-TabbedBlockTest">Tabbed Block Test</h2>
-<p></p><p><plain-text-body>
-<style type="text/css">
+<p></p><p>
+<style type="text/css">
DIV.deck DIV.tabBar DIV.tab { position: relative; top: 1px; background: #eee; }
DIV.deck DIV.tabBar DIV.tab#current { position: inherit; background: white; }
DIV.deck DIV.tabBar DIV.tab a { color: black; }
DIV.deck DIV.card {border: 1px solid #ccc; display: table-cell;}
-</style>
-</plain-text-body></p><p></p>
+</style>
+</p><p></p>
<h3 id="TestPage-Tabstest#1–usingCompositionmacro">Tabs test #1 –
using Composition macro</h3>
-<plain-text-body>{composition-setup}
-deck.tab.active.border=1px solid #ccc
-deck.tab.inactive.border=1px solid #ccc
-deck.tab.spacer=2px
-deck.startHidden=false
-{composition-setup}</plain-text-body>
+<script type="text/javascript">//<![CDATA[
+function debug() { }
+// ]]></script><script type="text/javascript"
src="/confluence/download/resources/org.randombits.confluence.composition:composition-setup/js/browser.js">//<![CDATA[
+// ]]></script><script type="text/javascript"
src="/confluence/download/resources/org.randombits.confluence.composition:composition-setup/js/behaviour.js">//<![CDATA[
+// ]]></script><script type="text/javascript"
src="/confluence/download/resources/org.randombits.confluence.composition:composition-setup/js/memory.js">//<![CDATA[
+// ]]></script><script type="text/javascript"
src="/confluence/download/resources/org.randombits.confluence.composition:composition-setup/js/cloak.js">//<![CDATA[
+// ]]></script><script type="text/javascript">//<![CDATA[
+Cloak.closeHTML = "<img
src=\'/confluence/download/resources/org.randombits.confluence.composition:toggle-cloak/img/navigate_down_10.gif\'/>";
+Cloak.openHTML = "<img
src=\'/confluence/download/resources/org.randombits.confluence.composition:toggle-cloak/img/navigate_right_10.gif\'/>";
+Cloak.toggleZone = true;
+Cloak.memoryDuration = 0;
+Cloak.memoryPrefix = "contentId:24189280";
+Cloak.memoryPath = "/confluence/";
+// ]]></script><style type="text/css">
+.cloakToggle { /* Definition for state toggling image */
+cursor:hand;
+cursor:pointer;
+}
+</style><script type="text/javascript"
src="/confluence/download/resources/org.randombits.confluence.composition:composition-setup/js/transitions.js">//<![CDATA[
+// ]]></script><script type="text/javascript"
src="/confluence/download/resources/org.randombits.confluence.composition:composition-setup/js/deck.js">//<![CDATA[
+// ]]></script><link rel="stylesheet" type="text/css"
href="/confluence/styles/main-action.css?pluginCompleteKey=org.randombits.confluence.composition:composition-setup&stylesheetName=deck&spaceKey=TAPESTRY"><script
type="text/javascript">//<![CDATA[
+Deck.memoryDuration = 0;
+Deck.memoryPrefix = "contentId:24189280";
+Deck.memoryPath = "/confluence/";
+// ]]></script>
-<plain-text-body>{deck:id=myDeck}</plain-text-body>
-<plain-text-body>{card:label=Tapestry 5.4+}</plain-text-body>
+<div class="deck" id="deck:myDeck" tablocation="top" style="display: none"
loopcards="false"><div class="cards tabbed">
+<div class="card" label="Tapestry 5.4+" labelrendered="Tapestry 5.4+">
<p>Starting with Tapestry 5.4, you can easily choose whether the foundation
JavaScript framework is jQuery or Prototype.</p>
-<plain-text-body>{card}</plain-text-body>
-<plain-text-body>{card:label=5.0-5.3}</plain-text-body>
+</div>
+<div class="card" label="5.0-5.3" labelrendered="5.0-5.3">
<p>In Tapestry versions prior to 5.4 the Prototype and Scriptaculous libraries
are included by default ... no extra download is required. Tapestry will
automatically link into your pages the prototype.js, scriptaculous.js, and
effects.js libraries, as well as the Tapestry library, tapestry.js (which
largely consists of support for form input validation). Starting with Tapestry
5.3, Underscore is also included.</p>
-<plain-text-body>{card}</plain-text-body>
-<plain-text-body>{deck}</plain-text-body>
+</div>
+</div></div>
<p>This works, but 1) doesn't preview very well (preview shows alternatives as
side-by-side cells in a table, with no header row), and 2) requires additional
processing code to be added to the SiteExporter.</p>
@@ -108,7 +137,7 @@ deck.startHidden=false
<h2 id="TestPage-ChildrenTest">Children Test</h2>
-<parameter ac:name="excerpt">true</parameter>
+<ul class="childpages-macro"><li><a href="test-page-2.html">Test Page
2</a></li></ul>
<p>foooo</p></div>
</div>
Modified: websites/production/tapestry/content/type-coercion.html
==============================================================================
--- websites/production/tapestry/content/type-coercion.html (original)
+++ websites/production/tapestry/content/type-coercion.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/shBrushJava.js'
type='text/javascript'></script>
+ <script>
+ SyntaxHighlighter.defaults['toolbar'] = false;
+ SyntaxHighlighter.all();
+ </script>
<link href="/styles/style.css" rel="stylesheet" type="text/css"/>
@@ -36,26 +44,13 @@
<div class="wrapper bs">
- <div id="navigation"><div class="nav"><ul class="alternate"><li><a
href="index.html">Home</a></li><li><a href="getting-started.html">Getting
Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a
href="download.html">Download</a></li><li><a
href="about.html">About</a></li><li><a class="external-link"
href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a
href="community.html">Community</a></li><li><a class="external-link"
href="http://www.apache.org/security/">Security</a></li><li><a
class="external-link" href="http://www.apache.org/">Apache</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div>
-
-</div>
+ <div id="navigation"><div class="nav"><ul class="alternate"><li><a
href="index.html">Home</a></li><li><a href="getting-started.html">Getting
Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a
href="download.html">Download</a></li><li><a
href="about.html">About</a></li><li><a class="external-link"
href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a
href="community.html">Community</a></li><li><a class="external-link"
href="http://www.apache.org/security/">Security</a></li><li><a
class="external-link" href="http://www.apache.org/">Apache</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div></div>
<div id="top">
- <div id="smallbanner"><div class="searchbox"
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999;
font-size: 90%">Tapestry docs, issues, wikis & blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get"
action="http://tapestry.apache.org/search.html">
- <input type="text" name="q">
- <input type="submit" value="Search">
-</form>
-
-</div>
-
-
-<div class="emblem" style="float:left"><p><a href="index.html"><span
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image
confluence-external-resource"
src="http://tapestry.apache.org/images/tapestry_small.png"
data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div>
-
-
-<div class="title" style="float:left; margin: 0 0 0 3em"><h1
id="SmallBanner-PageTitle">Type Coercion</h1></div>
-
-</div>
+ <div id="smallbanner"><div class="searchbox"
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999;
font-size: 90%">Tapestry docs, issues, wikis & blogs:</span><form
enctype="application/x-www-form-urlencoded" method="get"
action="http://tapestry.apache.org/search.html">
+ <input type="text" name="q">
+ <input type="submit" value="Search">
+</form></div><div class="emblem" style="float:left"><p><a
href="index.html"><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image confluence-external-resource"
src="http://tapestry.apache.org/images/tapestry_small.png"
data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div
class="title" style="float:left; margin: 0 0 0 3em"><h1
id="SmallBanner-PageTitle">Type Coercion</h1></div></div>
<div class="clearer"></div>
</div>
@@ -67,7 +62,20 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><p><strong>Type Coercion</strong>
is the conversion of one type of object to a new object of a different type
with similar content. Tapestry frequently must coerce objects from one type to
another. A common example is the coercion of string "5" into an integer 5 or a
double 5.0.</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 = "coercion" and space =
currentSpace()</parameter></rich-text-body><p>Although type coercions happen
more inside tapestry-core (including <a
href="parameter-type-coercion.html">coercions of <span
class="confluence-link">component parameters</span></a><span
class="confluence-link"> </span>), they may also happe
n inside tapestry-ioc, such as when injecting a value, rather than a service,
into a builder method.</p><p>Like everything else in Tapestry, type coercions
are extensible. At the root is the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/TypeCoercer.html">TypeCoercer</a>
service. Its configuration consists of a number of <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/CoercionTuple.html">CoercionTuples</a>.
Each tuple defines how to coerce from one type to another. The initial set of
coercions is focused primarily on coercions between different numeric
types:</p><p><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image"
src="type-coercion.data/type-coercer.png"></span></p><h2
id="TypeCoercion-DefaultTypeCoercions">Default Type Coercions</h2><p>There are
a few special coercions related to <code>null</code> there; <code>Object</code>
--> <code>List</code> wraps a lone object as a singleton list, we then need
<code>null</code> --> <code>List</code> to ensure that <code>null</code>
stays <code>null</code> (rather than a singleton list whose lone element is a
<code>null</code>).</p><p>Tapestry can <em>interpolate</em> necessary
coercions. For example, say it is necessary to coerce a
<code>StringBuffer</code> to an <code>Integer</code>; the TypeCoercer service
will chain together a series of coercions:</p><ul><li><code>Object</code>
--> <code>String</code></li><li><code>String</code> -->
<code>Long</code></li><li><code>Long</code> -->
<code>Integer</code></li></ul><h2 id="TypeCoercion-Coercingfromnull">Coercing
from null</h2><p>Coercing from <code>null</code> is special; it is not a
spanning search as with the other types. Either there is a specific coercion
from <code>null</code> to the desired type, or no coercion takes places (and
the coerced value is <code>null</code>).</p><p>The only built-in <co
de>null</code> coercion is from <code>null</code> to <code>boolean</code>
(which is always false).</p><h2 id="TypeCoercion-ListofCoercions">List of
Coercions</h2><p>As of Tapestry versions 5.1 and 5.2, the following coercions
are available:</p><plain-text-body>Double --> Float
+ <div id="ConfluenceContent"><p><strong>Type Coercion</strong>
is the conversion of one type of object to a new object of a different type
with similar content. Tapestry frequently must coerce objects from one type to
another. A common example is the coercion of string "5" into an integer 5 or a
double 5.0.</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="type-coercion.html">Type Coercion</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="parameter-type-coercion.html">Parameter Type Coercion</a>
+ </div> </li></ul></div><p>Although type coercions happen more inside
tapestry-core (including <a href="parameter-type-coercion.html">coercions of
<span class="confluence-link">component parameters</span></a><span
class="confluence-link"> </span>), they may also happen inside
tapestry-ioc, such as when injecting a value, rather than a service, into a
builder method.</p><p>Like everything else in Tapestry, type coercions are
extensible. At the root is the <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/TypeCoercer.html">TypeCoercer</a>
service. Its configuration consists of a number of <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/CoercionTuple.html">CoercionTuples</a>.
Each tuple defines how to coerce from one type to another. The initial set of
coercions is focused primarily on coercions between different numeric
types:</p><p><span class="confluence-emb
edded-file-wrapper"><img class="confluence-embedded-image"
src="type-coercion.data/type-coercer.png"></span></p><h2
id="TypeCoercion-DefaultTypeCoercions">Default Type Coercions</h2><p>There are
a few special coercions related to <code>null</code> there; <code>Object</code>
--> <code>List</code> wraps a lone object as a singleton list, we then need
<code>null</code> --> <code>List</code> to ensure that <code>null</code>
stays <code>null</code> (rather than a singleton list whose lone element is a
<code>null</code>).</p><p>Tapestry can <em>interpolate</em> necessary
coercions. For example, say it is necessary to coerce a
<code>StringBuffer</code> to an <code>Integer</code>; the TypeCoercer service
will chain together a series of coercions:</p><ul><li><code>Object</code>
--> <code>String</code></li><li><code>String</code> -->
<code>Long</code></li><li><code>Long</code> -->
<code>Integer</code></li></ul><h2 id="TypeCoercion-Coercingfromnull">Coercing
from null</h2><p>Coe
rcing from <code>null</code> is special; it is not a spanning search as with
the other types. Either there is a specific coercion from <code>null</code> to
the desired type, or no coercion takes places (and the coerced value is
<code>null</code>).</p><p>The only built-in <code>null</code> coercion is from
<code>null</code> to <code>boolean</code> (which is always false).</p><h2
id="TypeCoercion-ListofCoercions">List of Coercions</h2><p>As of Tapestry
versions 5.1 and 5.2, the following coercions are available:</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;">Double --> Float
Float --> Double
Long --> Boolean
Long --> Byte
@@ -120,7 +128,9 @@ org.apache.tapestry5.Renderable --> o
org.apache.tapestry5.ioc.util.TimeInterval --> Long
org.apache.tapestry5.runtime.ComponentResourcesAware -->
org.apache.tapestry5.ComponentResources
short[] --> java.util.List
-</plain-text-body><h2 id="TypeCoercion-ContributingNewCoercions">Contributing
New Coercions</h2><p>TypeCoercer is extensible; you may add new coercions as
desired. For example, let's say you have a <code>Money</code> type that
represents an amount of some currency, and you want to be able to convert from
<code>BigDecimal</code> to <code>Money</code>. Further, let's assume that
<code>Money</code> has a constructor that accepts a <code>BigDecimal</code> as
its parameter. We'll use a little Tapestry IOC configuration jujitsu to inform
the TypeCoercer about this coercion.</p><parameter
ac:name="title">AppModule.java (partial)</parameter><plain-text-body>public
static void contributeTypeCoercer(Configuration<CoercionTuple>
configuration)
+</pre>
+</div></div><h2 id="TypeCoercion-ContributingNewCoercions">Contributing New
Coercions</h2><p>TypeCoercer is extensible; you may add new coercions as
desired. For example, let's say you have a <code>Money</code> type that
represents an amount of some currency, and you want to be able to convert from
<code>BigDecimal</code> to <code>Money</code>. Further, let's assume that
<code>Money</code> has a constructor that accepts a <code>BigDecimal</code> as
its parameter. We'll use a little Tapestry IOC configuration jujitsu to inform
the TypeCoercer about this coercion.</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeHeader panelHeader pdl"
style="border-bottom-width: 1px;"><b>AppModule.java (partial)</b></div><div
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public static void
contributeTypeCoercer(Configuration<CoercionTuple> configuration)
{
Coercion<BigDecimal, Money> coercion = new Coercion<BigDecimal,
Money>()
{
@@ -131,7 +141,9 @@ short[] --> java.util.List
};
configuration.add(new CoercionTuple<BigDecimal,
Money>(BigDecimal.class, Money.class, coercion));
-}</plain-text-body><p>Further, since TypeCoercer knows how to convert
<code>Double</code> to <code>BigDecimal</code>, or even <code>Integer</code>
(to <code>Long</code> to <code>Double</code>) to <code>BigDecimal</code>, all
of those coercions would work as well.</p><p>When creating a coercion from
<code>null</code>, use <code>Void.class</code> as the source type. For example,
the built-in coercion from <code>null</code> to <code>Boolean</code> is
implemented as:</p><parameter ac:name="title">AppModule.java
(partial)</parameter><plain-text-body> configuration.add(new
CoercionTuple(void.class, Boolean.class,
+}</pre>
+</div></div><p>Further, since TypeCoercer knows how to convert
<code>Double</code> to <code>BigDecimal</code>, or even <code>Integer</code>
(to <code>Long</code> to <code>Double</code>) to <code>BigDecimal</code>, all
of those coercions would work as well.</p><p>When creating a coercion from
<code>null</code>, use <code>Void.class</code> as the source type. For example,
the built-in coercion from <code>null</code> to <code>Boolean</code> is
implemented as:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeHeader panelHeader pdl" style="border-bottom-width:
1px;"><b>AppModule.java (partial)</b></div><div class="codeContent panelContent
pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> configuration.add(new CoercionTuple(void.class,
Boolean.class,
new Coercion<Void, Boolean>()
{
public Boolean coerce(Void input)
@@ -139,7 +151,8 @@ short[] --> java.util.List
return false;
}
}));
-</plain-text-body><p> </p><p></p></div>
+</pre>
+</div></div><p> </p><p></p></div>
</div>
<div class="clearer"></div>
Modified:
websites/production/tapestry/content/unit-testing-pages-or-components.html
==============================================================================
--- websites/production/tapestry/content/unit-testing-pages-or-components.html
(original)
+++ websites/production/tapestry/content/unit-testing-pages-or-components.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/shBrushJava.js'
type='text/javascript'></script>
+ <script>
+ SyntaxHighlighter.defaults['toolbar'] = false;
+ SyntaxHighlighter.all();
+ </script>
<link href="/styles/style.css" rel="stylesheet" type="text/css"/>
@@ -36,26 +44,13 @@
<div class="wrapper bs">
- <div id="navigation"><div class="nav"><ul class="alternate"><li><a
href="index.html">Home</a></li><li><a href="getting-started.html">Getting
Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a
href="download.html">Download</a></li><li><a
href="about.html">About</a></li><li><a class="external-link"
href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a
href="community.html">Community</a></li><li><a class="external-link"
href="http://www.apache.org/security/">Security</a></li><li><a
class="external-link" href="http://www.apache.org/">Apache</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div>
-
-</div>
+ <div id="navigation"><div class="nav"><ul class="alternate"><li><a
href="index.html">Home</a></li><li><a href="getting-started.html">Getting
Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a
href="download.html">Download</a></li><li><a
href="about.html">About</a></li><li><a class="external-link"
href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a
href="community.html">Community</a></li><li><a class="external-link"
href="http://www.apache.org/security/">Security</a></li><li><a
class="external-link" href="http://www.apache.org/">Apache</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a
class="external-link"
href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div></div>
<div id="top">
- <div id="smallbanner"><div class="searchbox"
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999;
font-size: 90%">Tapestry docs, issues, wikis & blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get"
action="http://tapestry.apache.org/search.html">
- <input type="text" name="q">
- <input type="submit" value="Search">
-</form>
-
-</div>
-
-
-<div class="emblem" style="float:left"><p><a href="index.html"><span
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image
confluence-external-resource"
src="http://tapestry.apache.org/images/tapestry_small.png"
data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div>
-
-
-<div class="title" style="float:left; margin: 0 0 0 3em"><h1
id="SmallBanner-PageTitle">Unit testing pages or components</h1></div>
-
-</div>
+ <div id="smallbanner"><div class="searchbox"
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999;
font-size: 90%">Tapestry docs, issues, wikis & blogs:</span><form
enctype="application/x-www-form-urlencoded" method="get"
action="http://tapestry.apache.org/search.html">
+ <input type="text" name="q">
+ <input type="submit" value="Search">
+</form></div><div class="emblem" style="float:left"><p><a
href="index.html"><span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image confluence-external-resource"
src="http://tapestry.apache.org/images/tapestry_small.png"
data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div
class="title" style="float:left; margin: 0 0 0 3em"><h1
id="SmallBanner-PageTitle">Unit testing pages or components</h1></div></div>
<div class="clearer"></div>
</div>
@@ -67,7 +62,20 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><p>Tapestry provides support for
easily <strong>unit testing your pages and components</strong>. Follow the
simple steps below.</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 = "testing" and space =
currentSpace()</parameter></rich-text-body><h2
id="Unittestingpagesorcomponents-Settingupadrivingenvironment">Setting up a
driving environment</h2><p>In order to unit test a page, you'll need to create
an instance of <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/PageTester.html">PageTester</a>.
It acts as both the browser and the servlet container so that you can use it
to drive your page
.</p><p>The PageTester falls into a middle ground between pure unit testing
and <a href="integration-testing.html">full-scale integration
testing</a>.</p><p>As the PageTester is not a real servlet container, you need
to tell it the same information as you would in web.xml:</p><ol><li>Your
application package.</li><li>Your filter name. This is used to load your
Tapestry IoC module only. If you have none, you can pass an empty string or
anything to it.</li><li>The folder acting as your context root. This is used to
locate your templates (if they're put there).Here is an example (using TestNG,
but you're free to use JUnit or anything else):</li></ol><parameter
ac:name="">java</parameter><plain-text-body>public class MyTest extends Assert
+ <div id="ConfluenceContent"><p>Tapestry provides support for
easily <strong>unit testing your pages and components</strong>. Follow the
simple steps below.</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="integration-testing.html">Integration Testing</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="unit-testing-pages-or-components.html">Unit testing pages or
components</a>
+ </div> </li></ul></div><h2
id="Unittestingpagesorcomponents-Settingupadrivingenvironment">Setting up a
driving environment</h2><p>In order to unit test a page, you'll need to create
an instance of <a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/PageTester.html">PageTester</a>.
It acts as both the browser and the servlet container so that you can use it
to drive your page.</p><p>The PageTester falls into a middle ground between
pure unit testing and <a href="integration-testing.html">full-scale
integration testing</a>.</p><p>As the PageTester is not a real servlet
container, you need to tell it the same information as you would in
web.xml:</p><ol><li>Your application package.</li><li>Your filter name. This is
used to load your Tapestry IoC module only. If you have none, you can pass an
empty string or anything to it.</li><li>The folder acting as your context root.
This is used to locate your templates (if they're put there).Here
is an example (using TestNG, but you're free to use JUnit or anything
else):</li></ol><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 MyTest extends Assert
{
@Test
public void test1()
@@ -77,7 +85,9 @@
PageTester tester = new PageTester(appPackage, appName,
"src/main/webapp");
}
}
-</plain-text-body><h2
id="Unittestingpagesorcomponents-Testingtherenderingofapage">Testing the
rendering of a page</h2><p>To test if a page renders properly (optionally with
context), you can tell the PageTester to render it and then assert against the
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/dom/Document.html">DOM
Document</a> returned.</p><p>Here is an example. Let's assuming the page being
tested is named "MyPage" and it should return a page containing an HTML element
whose id is "id1" and whose text content should be "hello":</p><parameter
ac:name="">java</parameter><plain-text-body>public class MyTest extends Assert
+</pre>
+</div></div><h2
id="Unittestingpagesorcomponents-Testingtherenderingofapage">Testing the
rendering of a page</h2><p>To test if a page renders properly (optionally with
context), you can tell the PageTester to render it and then assert against the
<a class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/dom/Document.html">DOM
Document</a> returned.</p><p>Here is an example. Let's assuming the page being
tested is named "MyPage" and it should return a page containing an HTML element
whose id is "id1" and whose text content should be "hello":</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 MyTest extends Assert
{
@Test
public void test1()
@@ -89,7 +99,9 @@
assertEquals(doc.getElementById("id1").getChildText(), "hello");
}
}
-</plain-text-body><p>If the page requires a context, you can pass it this
way:</p><parameter ac:name="">java</parameter><plain-text-body>public class
MyTest extends Assert
+</pre>
+</div></div><p>If the page requires a context, you can pass it this
way:</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 MyTest extends Assert
{
@Test
public void test1()
@@ -102,7 +114,9 @@
assertEquals(doc.getElementById("id1").getChildText(), "hello");
}
}
-</plain-text-body><h2
id="Unittestingpagesorcomponents-Testinganactionlink">Testing an action
link</h2><p>After rendering a page, you may want to "click" on an action link
and then assert against the resulting page. You can do it this
way:</p><parameter ac:name="">java</parameter><plain-text-body>public class
MyTest extends Assert
+</pre>
+</div></div><h2 id="Unittestingpagesorcomponents-Testinganactionlink">Testing
an action link</h2><p>After rendering a page, you may want to "click" on an
action link and then assert against the resulting page. You can do it this
way:</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 MyTest extends Assert
{
@Test
public void test1()
@@ -116,7 +130,9 @@
assertTrue(doc.toString().contains("abc"));
}
}
-</plain-text-body><h2
id="Unittestingpagesorcomponents-Testingaformsubmission">Testing a form
submission</h2><p>After rendering a page, you may want to fill out a form,
submit it and then inspect the resulting page. You can do it this
way:</p><parameter ac:name="">java</parameter><plain-text-body>public class
MyTest extends Assert
+</pre>
+</div></div><h2
id="Unittestingpagesorcomponents-Testingaformsubmission">Testing a form
submission</h2><p>After rendering a page, you may want to fill out a form,
submit it and then inspect the resulting page. You can do it this way:</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 MyTest extends Assert
{
@Test
public void test1()
@@ -133,7 +149,8 @@
assertTrue(doc.toString().contains("abc"));
}
}
-</plain-text-body><p>To submit a form by clicking a submit button, call the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/PageTester.html#clickSubmit(org.apache.tapestry5.dom.Element,%20java.util.Map)">clickSubmit()</a>
method instead.</p><h2
id="Unittestingpagesorcomponents-Unittestingacomponent">Unit testing a
component</h2><p>To unit test a component, just create a test page containing
that component. Then unit test that page.</p><h2
id="Unittestingpagesorcomponents-Third-partyTestingModules">Third-party Testing
Modules</h2><ul><li><a class="external-link"
href="http://tapestrytestify.sourceforge.net/"
rel="nofollow">Tapestry-Testify</a> makes it easier to write page and component
tests and run them efficiently.</li><li><a class="external-link"
href="http://tapestryxpath.sourceforge.net/" rel="nofollow">Tapestry-XPath</a>
allows you to use XPath expressions to query the Tapestry DOM (useful for
simplifying page and componen
t tests).</li></ul></div>
+</pre>
+</div></div><p>To submit a form by clicking a submit button, call the <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/test/PageTester.html#clickSubmit(org.apache.tapestry5.dom.Element,%20java.util.Map)">clickSubmit()</a>
method instead.</p><h2
id="Unittestingpagesorcomponents-Unittestingacomponent">Unit testing a
component</h2><p>To unit test a component, just create a test page containing
that component. Then unit test that page.</p><h2
id="Unittestingpagesorcomponents-Third-partyTestingModules">Third-party Testing
Modules</h2><ul><li><a class="external-link"
href="http://tapestrytestify.sourceforge.net/"
rel="nofollow">Tapestry-Testify</a> makes it easier to write page and component
tests and run them efficiently.</li><li><a class="external-link"
href="http://tapestryxpath.sourceforge.net/" rel="nofollow">Tapestry-XPath</a>
allows you to use XPath expressions to query the Tapestry DOM (useful for
simplifying page and component test
s).</li></ul></div>
</div>
<div class="clearer"></div>
Modified: websites/production/tapestry/content/uploading-files.html
==============================================================================
--- websites/production/tapestry/content/uploading-files.html (original)
+++ websites/production/tapestry/content/uploading-files.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,20 +77,24 @@
</div>
<div id="content">
- <div id="ConfluenceContent"><p>Tapestry provides a file upload
component based on <a class="external-link"
href="http://commons.apache.org/fileupload/">Apache Commons FileUpload</a> to
make it easier to handle files uploaded through web forms (via the standard
<input type="file"> HTML element).</p><h1
id="UploadingFiles-Downloading">Downloading</h1><p><strong>tapestry-upload</strong>
is not automatically included in Tapestry applications because of the
additional dependencies it requires. To include it, just add the
<code>tapestry-upload</code> dependency to the pom of your application,
something like this:</p><parameter
ac:name="language">xml</parameter><plain-text-body><dependency>
+ <div id="ConfluenceContent"><p>Tapestry provides a file upload
component based on <a class="external-link"
href="http://commons.apache.org/fileupload/">Apache Commons FileUpload</a> to
make it easier to handle files uploaded through web forms (via the standard
<input type="file"> HTML element).</p><h1
id="UploadingFiles-Downloading">Downloading</h1><p><strong>tapestry-upload</strong>
is not automatically included in Tapestry applications because of the
additional dependencies it requires. To include it, just add the
<code>tapestry-upload</code> dependency to the pom of your application,
something like this:</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;"><dependency>
<groupId>org.apache.tapestry</groupId>
<artifactId>tapestry-upload</artifactId>
<version>${tapestry-release-version}</version>
</dependency>
-</plain-text-body><p>If you aren't using Maven, you'll have to download the
jar and its dependencies yourself.</p><h1
id="UploadingFiles-Usage">Usage</h1><p>The upload component supports default
value binding (based on id) and
validation.</p><plain-text-body>{float:right|background=#eee|padding=0 1em}
- *JumpStart Demo:*
- [File
Upload|http://jumpstart.doublenegative.com.au/jumpstart/examples/javascript/fileupload]
-{float}</plain-text-body><h2 id="UploadingFiles-ComponentTemplate">Component
Template</h2><parameter ac:name="language">java</parameter><plain-text-body>
<t:form>
+</pre>
+</div></div><p>If you aren't using Maven, you'll have to download the jar and
its dependencies yourself.</p><h1 id="UploadingFiles-Usage">Usage</h1><p>The
upload component supports default value binding (based on id) and
validation.</p><div class="navmenu" style="float:right; background:#eee;
margin:3px; padding:0 1em">
+<p> <strong>JumpStart Demo:</strong><br clear="none">
+ <a class="external-link"
href="http://jumpstart.doublenegative.com.au/jumpstart/examples/javascript/fileupload"
rel="nofollow">File Upload</a></p></div><h2
id="UploadingFiles-ComponentTemplate">Component Template</h2><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> <t:form>
<t:errors/>
<input t:type="upload" t:id="file" t:value="file"
validate="required"/>
<br/>
<input type="submit" value="Upload"/>
- </t:form></plain-text-body><p>Here, because the value parameter was
not bound, the component used the file property of its container (because the
component's id is 'file'). If you want to upload as a different property,
either bind the value parameter or change the component's id.</p><h2
id="UploadingFiles-Pageclass">Page class</h2><parameter
ac:name="language">java</parameter><plain-text-body> public class
UploadExample
+ </t:form></pre>
+</div></div><p>Here, because the value parameter was not bound, the component
used the file property of its container (because the component's id is 'file').
If you want to upload as a different property, either bind the value parameter
or change the component's id.</p><h2 id="UploadingFiles-Pageclass">Page
class</h2><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 UploadExample
{
@Property
private UploadedFile file;
@@ -91,7 +105,9 @@
file.write(copied);
}
- }</plain-text-body><h1 id="UploadingFiles-UploadExceptions">Upload
Exceptions</h1><p>In some cases, file uploads may fail. This can be because of
a simple communication exception, or more likely, because the configured
maximum upload size was exceeded.</p><p>When a file upload exception occurs,
Tapestry will trigger a "uploadException" event on the page to notify it of the
error. All other normal processing is skipped (no "activate" event, no form
submission, etc.).</p><p>The event handler should return a non-null object,
which will be handled as a navigational result. Example:</p><parameter
ac:name="language">java</parameter><plain-text-body>
@Persist(PersistenceConstants.FLASH)
+ }</pre>
+</div></div><h1 id="UploadingFiles-UploadExceptions">Upload
Exceptions</h1><p>In some cases, file uploads may fail. This can be because of
a simple communication exception, or more likely, because the configured
maximum upload size was exceeded.</p><p>When a file upload exception occurs,
Tapestry will trigger a "uploadException" event on the page to notify it of the
error. All other normal processing is skipped (no "activate" event, no form
submission, etc.).</p><p>The event handler should return a non-null object,
which will be handled as a navigational result. Example:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"> @Persist(PersistenceConstants.FLASH)
@Property
private String message;
@@ -101,7 +117,8 @@
message = "Upload exception: " + ex.getMessage();
return this;
- }</plain-text-body><p>Note the importance of <code>return this;</code>. A
void event handler method, or one that returns null, will result in the
FileUploadException being reported to the user as an uncaught runtime
exception.</p><h1 id="UploadingFiles-Configuration">Configuration</h1><p>Four
values may be configured as <a href="symbols.html">symbols</a>:</p><div
class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1"
rowspan="1" class="confluenceTh"><p>upload.repository-location</p></th><td
colspan="1" rowspan="1" class="confluenceTd"><p>The directory to which files
that are too large to keep in memory will be written to. The default is from
the java.io.tmpdir system property.</p></td></tr><tr><th colspan="1"
rowspan="1" class="confluenceTh"><p>upload.repository-threshold</p></th><td
colspan="1" rowspan="1" class="confluenceTd"><p>Upload size, in bytes, at which
point the uploaded file is written to disk rather than kept in memory. The
default is 10 kiloby
tes.</p></td></tr><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>upload.requestsize-max</p></th><td colspan="1"
rowspan="1" class="confluenceTd"><p>Maximim size, in bytes, for the overall
request. If exceeded, a FileUploadException will occur. The default is no
maximum.</p></td></tr><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>upload.filesize-max</p></th><td colspan="1" rowspan="1"
class="confluenceTd"><p>Maximum size, in bytes, for any individual uploaded
file. Again, a FileUploadException will occur if exceeded. The default is no
maximum.</p></td></tr></tbody></table></div><p>The class <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/upload/services/UploadSymbols.html">UploadSymbols</a>
defines constants for all four of these.</p><h1
id="UploadingFiles-PotentialIssues">Potential Issues</h1><p>The Commons
FileUpload library uses the CommonsIO file cleaner service to remove temporary
files when they are no longer nee
ded. This service creates a thread to carry out its work. If the commons-io
library is shared amongst multiple applications (e.g. added to server
classpath) it is possible for an application to terminate this thread
prematurely and cause errors for the other applications. (see the <a
class="external-link"
href="http://jakarta.apache.org/commons/fileupload/using.html">Resource
Cleanup</a> section in for more discussion)</p><p>Technically the file cleanup
service is not needed by Tapestry Upload (which deletes temporary files at the
end of request processing). However it is currently not possible to disable it
(enhancement request has been filed as <a class="external-link"
href="https://issues.apache.org/jira/browse/FILEUPLOAD-133">FILEUPLOAD-133</a>).</p></div>
+ }</pre>
+</div></div><p>Note the importance of <code>return this;</code>. A void event
handler method, or one that returns null, will result in the
FileUploadException being reported to the user as an uncaught runtime
exception.</p><h1 id="UploadingFiles-Configuration">Configuration</h1><p>Four
values may be configured as <a href="symbols.html">symbols</a>:</p><div
class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1"
rowspan="1" class="confluenceTh"><p>upload.repository-location</p></th><td
colspan="1" rowspan="1" class="confluenceTd"><p>The directory to which files
that are too large to keep in memory will be written to. The default is from
the java.io.tmpdir system property.</p></td></tr><tr><th colspan="1"
rowspan="1" class="confluenceTh"><p>upload.repository-threshold</p></th><td
colspan="1" rowspan="1" class="confluenceTd"><p>Upload size, in bytes, at which
point the uploaded file is written to disk rather than kept in memory. The
default is 10 kilobytes.</p></t
d></tr><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>upload.requestsize-max</p></th><td colspan="1"
rowspan="1" class="confluenceTd"><p>Maximim size, in bytes, for the overall
request. If exceeded, a FileUploadException will occur. The default is no
maximum.</p></td></tr><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>upload.filesize-max</p></th><td colspan="1" rowspan="1"
class="confluenceTd"><p>Maximum size, in bytes, for any individual uploaded
file. Again, a FileUploadException will occur if exceeded. The default is no
maximum.</p></td></tr></tbody></table></div><p>The class <a
class="external-link"
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/upload/services/UploadSymbols.html">UploadSymbols</a>
defines constants for all four of these.</p><h1
id="UploadingFiles-PotentialIssues">Potential Issues</h1><p>The Commons
FileUpload library uses the CommonsIO file cleaner service to remove temporary
files when they are no longer needed. This s
ervice creates a thread to carry out its work. If the commons-io library is
shared amongst multiple applications (e.g. added to server classpath) it is
possible for an application to terminate this thread prematurely and cause
errors for the other applications. (see the <a class="external-link"
href="http://jakarta.apache.org/commons/fileupload/using.html">Resource
Cleanup</a> section in for more discussion)</p><p>Technically the file cleanup
service is not needed by Tapestry Upload (which deletes temporary files at the
end of request processing). However it is currently not possible to disable it
(enhancement request has been filed as <a class="external-link"
href="https://issues.apache.org/jira/browse/FILEUPLOAD-133">FILEUPLOAD-133</a>).</p></div>
</div>
<div class="clearer"></div>