Modified: websites/production/tapestry/content/strategybuilder-service.html
==============================================================================
--- websites/production/tapestry/content/strategybuilder-service.html (original)
+++ websites/production/tapestry/content/strategybuilder-service.html Sun Apr 
26 21:22:55 2020
@@ -84,11 +84,13 @@
 
 
 
+
+
 <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="shadowbuilder-service.html">ShadowBuilder 
Service</a>
@@ -97,25 +99,25 @@
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  
href="strategybuilder-service.html">StrategyBuilder Service</a>
+                        <a  
href="pipelinebuilder-service.html">PipelineBuilder Service</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  
href="pipelinebuilder-service.html">PipelineBuilder Service</a>
+                        <a  
href="strategybuilder-service.html">StrategyBuilder Service</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="chainbuilder-service.html">ChainBuilder 
Service</a>
@@ -127,12 +129,12 @@
 
 
 <p>Another of the Gang Of Four patterns, the strategy pattern as implemented 
in Tapestry IoC is a kind of late binding.</p><p>The idea is that 
<em>adapters</em> for objects are accessed based on the <em>actual type</em> of 
an object. These adapters supply additional functionality. The adapters are 
located using a StrategyRegistry (<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/util/StrategyRegistry.html";>API</a>).</p><p>The
 lookup of adapters is based on an inheritance search; thus providing an 
adapter for type java.util.Map will match any object that implements the Map 
interface. The inheritance search works its way up the class hierarchy looking 
for a matching registration. If nothing is found, then all the interfaces 
directly or indirectly implemented by the selector class are checked. 
java.lang.Object is always the final match.</p><p>A runtime exception is thrown 
if no match can be found.</p><p>As a special case, the value nul
 l is searched for as if it were an instance of the class void.</p><p>The 
StrategyBuilder service (<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/StrategyBuilder.html";>API</a>)
 creates a service implementation around a strategy registry.</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 interface StrategyBuilder
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public interface 
StrategyBuilder
 {
     &lt;S&gt; S build(StrategyRegistry&lt;S&gt; registry);
 }</pre>
 </div></div><p>For a given interface (and matching StrategyRegistry), a 
service implementation is created. The service interface is determined from the 
strategy registry.</p><p>The first parameter of each method is the 
<em>selector</em>. Its type is used to locate an adapter.</p><p>The 
corresponding method of the adapter is then invoked, passing all 
parameters.</p><p>Every method of the service interface should take at least 
one parameter. Generally, such interfaces have only one or two methods.</p><h1 
id="StrategyBuilderService-Example">Example</h1><p>You will usually have a 
service configuration for defining the adapter registry.</p><p>You convert the 
configuration into a StrategyRegistry, and use that to build the final 
service:</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 static MyStrategyService build(Map&lt;Class, 
MyStrategyService&gt; configuration,
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static 
MyStrategyService build(Map&lt;Class, MyStrategyService&gt; configuration,
     @InjectService("StrategyBuilder")
     StrategyBuilder builder)
   {

Modified: 
websites/production/tapestry/content/supporting-informal-parameters.html
==============================================================================
--- websites/production/tapestry/content/supporting-informal-parameters.html 
(original)
+++ websites/production/tapestry/content/supporting-informal-parameters.html 
Sun Apr 26 21:22:55 2020
@@ -84,38 +84,40 @@
 
 
 
+
+
 <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="enum-parameter-recipe.html">Enum Parameter 
Recipe</a>
+                        <a  
href="supporting-informal-parameters.html">Supporting Informal Parameters</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  
href="supporting-informal-parameters.html">Supporting Informal Parameters</a>
+                        <a  href="default-parameter.html">Default Parameter</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="default-parameter.html">Default Parameter</a>
+                        <a  href="enum-parameter-recipe.html">Enum Parameter 
Recipe</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="component-parameters.html">Component 
Parameters</a>
@@ -127,7 +129,7 @@
 
 
 <p>Any component that closely emulates a particular HTML element 
<strong><em>should</em></strong> support informal parameters, because it gives 
users of your component the ability to easily add HTML attributes to the HTML 
that your component emits. You'll find that most of the built-in Tapestry 
components, such as Form, Label and TextField, do exactly that.</p><p>To 
support informal parameters, a component class should use either the @<a  
class="external-link" 
href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/annotations/SupportsInformalParameters.html";>SupportsInformalParameters</a>
 annotation or the RenderInformals mixin. Otherwise, providing informal 
parameters to a component will do nothing: any additional parameters will be 
ignored.</p><h3 
id="SupportingInformalParameters-Approach1:@SupportsInformalParameters">Approach
 1: @SupportsInformalParameters</h3><p>In the example below we create an Img 
component, a custom replacement for the &lt;img&gt; tag. Its sr
 c parameter will be an asset. We'll use the @SupportsInformalParameters 
annotation to tell Tapestry that the component should support informal 
parameters.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Img.java</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@SupportsInformalParameters
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">@SupportsInformalParameters
 public class Img
 {
     @Parameter(required=true, allowNull=false, 
defaultPrefix=BindingConstants.ASSET)
@@ -146,7 +148,7 @@ public class Img
 }
 </pre>
 </div></div><p>The call to renderInformalParameters() is what converts and 
outputs the informal parameters. It should occur <em>after</em> your code has 
rendered attributes into the element (earlier written attributes will 
<em>not</em> be overwritten by later written attributes).</p><p>Returning false 
from beginRender() ensures that the body of the component is not rendered, 
which makes sense for an &lt;img&gt; tag, which has no body.</p><h3 
id="SupportingInformalParameters-Approach2:RenderInformals">Approach 2: 
RenderInformals</h3><p>Another, equivalent, approach is to use the <a  
class="external-link" 
href="http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/corelib/mixins/RenderInformals.html";>RenderInformals</a>
 mixin (:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>Img.java</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class Img
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class Img
 {
     @Parameter(required=true, allowNull=false, 
defaultPrefix=BindingConstants.ASSET)
     private Asset src;
@@ -167,7 +169,7 @@ public class Img
 }
 </pre>
 </div></div><p>This variation splits the rendering of the tag in two pieces, 
so that the RenderInformals mixin can operate (after beginRender() and before 
beforeRenderBody()).</p><h3 
id="SupportingInformalParameters-Approach3:Extendthe&quot;Any&quot;component">Approach
 3: Extend the "Any" component</h3><p>Another approach is to have your 
component class <em>extend</em> Tapestry's Any component, which already 
supports informal parameters:</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Img.java</b></div><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class Img extends Any { ... }</pre>
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class Img extends 
Any { ... }</pre>
 </div></div><p>&#160;</p><p>&#160;</p><p>&#160;</p><p>&#160;</p></div>
       </div>
 

Modified: websites/production/tapestry/content/switching-cases.html
==============================================================================
--- websites/production/tapestry/content/switching-cases.html (original)
+++ websites/production/tapestry/content/switching-cases.html Sun Apr 26 
21:22:55 2020
@@ -82,7 +82,7 @@
 
 
 <p>In cases where you have to distinguish multiple cases, the 
<code>Delegate</code> component comes in. It delegates rendering to some other 
component, for example a <code>Block</code>. For each case you have, you 
basically wrap the content inside a <code>Block</code> that doesn't get 
rendered by default. You then place a Delegate component on your page and point 
it to a method inside your page class that will decide which of your Blocks 
should be rendered.</p><p>Imagine for example a use case, where you want to 
distinguish between 4 cases and you have an int property called 
<code>whichCase</code> that should be tested against. Your page template would 
look as follows:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 
1px;"><b>SwitchMe.tml</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;html 
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"&gt;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml; 
gutter: false; theme: Default" data-theme="Default">&lt;html 
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"&gt;
     &lt;body&gt;
         &lt;h1&gt;Switch&lt;/h1&gt;
 
@@ -107,7 +107,7 @@
 &lt;/html&gt;
 </pre>
 </div></div><p>You can see, that the <code>Delegate</code> component's 
<code>to</code> parameter is bound to the case property of your page class. In 
your page class you therefore have a <code>getCase()</code> method that is 
responsible for telling the <code>Delegate</code> component which component 
should be rendered. For that we are injecting references to the <code>Block}}s 
defined in your page template into the page class and return the according 
{{Block</code> in the <code>getCase()</code> method.</p><div class="code panel 
pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>SwitchMe.java</b></div><div 
class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class SwitchMe
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class SwitchMe
 {
     @Persist
     private int whichCase;

Modified: websites/production/tapestry/content/symbols.html
==============================================================================
--- websites/production/tapestry/content/symbols.html (original)
+++ websites/production/tapestry/content/symbols.html Sun Apr 26 21:22:55 2020
@@ -85,38 +85,40 @@
 
 
 
+
+
 <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  
href="application-module-class-cheat-sheet.html">Application Module Class Cheat 
Sheet</a>
+                        <a  href="response-compression.html">Response 
Compression</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  
href="ioc-cookbook-service-configurations.html">IoC cookbook - Service 
Configurations</a>
+                        <a  href="symbols.html">Symbols</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="symbols.html">Symbols</a>
+                        <a  
href="application-module-class-cheat-sheet.html">Application Module Class Cheat 
Sheet</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="tapestry-ioc-configuration.html">Tapestry 
IoC Configuration</a>
@@ -125,16 +127,16 @@
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="response-compression.html">Response 
Compression</a>
+                        <a  
href="ioc-cookbook-service-configurations.html">IoC cookbook - Service 
Configurations</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="configuration.html">Configuration</a>
@@ -146,16 +148,16 @@
 
 
 <h2 id="Symbols-Syntax">Syntax</h2><p>The syntax of symbols is based on Ant 
expressions. That is, the name is surrounded by ${ and } characters:</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;">${some.symbol.name}
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">${some.symbol.name}
 </pre>
 </div></div><p>The value on the inside is the <em>symbol name</em>. By 
convention, the symbol name is segmented with periods (for example, 
"tapestry.production-mode").</p><h2 id="Symbols-Built-inSymbols">Built-in 
Symbols</h2><p class="confluence-link">The&#160;<a  
href="configuration.html">Configuration</a> page lists most of the symbol names 
used by Tapestry's built-in services.</p><h2 
id="Symbols-UsingSymbolsinyourServices">Using Symbols in your 
Services</h2><p>Symbols are used inside the @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Value.html";>Value</a>
 and @<a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/InjectService.html";>InjectService</a>
 annotations.</p><p>For 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;">  public static MyService build(
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static MyService 
build(
       @InjectService("${some-service-id}") Collaborator collab)
   {
     return . . . ;
   }</pre>
 </div></div><p>Here, the symbol name, <code>some-service-id</code> is a 
service id, such as <code>WackyCollaborator</code>.</p><p>Although not shown 
here, it is possible to use multiple symbols inside the string, or mix literal 
text with symbols.</p><h2 id="Symbols-InjectingValuesfromSymbols">Injecting 
Values from Symbols</h2><p>You may also inject symbol values. For example, if 
you are interested in whether the application is in production mode or 
developer mode:</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 MyService implements MyServiceInterface
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class MyService 
implements MyServiceInterface
 {
   public MyService(@Value("${tapestry.production-mode}") boolean 
productionMode, ...)
   {
@@ -163,7 +165,7 @@
       . . .
 </pre>
 </div></div><p>Here Tapestry has <a  href="type-coercion.html">coerced</a> the 
"tapestry.production-mode" symbol to a boolean to be injected.</p><p>As an 
alternative, the @Symbol annotation, may be used:</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 MyService implements MyServiceInterface
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class MyService 
implements MyServiceInterface
 {
   public MyService(@Symbol(SymbolConstants.PRODUCTION_MODE) boolean 
productionMode, ...)
   {
@@ -171,7 +173,7 @@
       . . .
 </pre>
 </div></div><p>This is very useful when a constant value is defined for the 
symbol; it means that the compiler can catch a typo, rather than detecting it a 
runtime.</p><p><strong>Note:</strong> When injecting a symbol as a 
<em>string</em> into a service, you must use the @Inject annotation as well as 
@Value or @Symbol; otherwise Tapestry will inject the service's service 
id.</p><h2 id="Symbols-SymbolsinComponentClassesandTemplates">Symbols in 
Component Classes and Templates</h2><p>It's easy to use a symbol in a component 
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;">  @Inject
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  @Inject
   @Symbol(SymbolConstants.PRODUCTION_MODE)
   private boolean productionMode;
   . . .
@@ -181,16 +183,16 @@
     }
   }</pre>
 </div></div><p>You can even use them directly in a component template, using 
the "symbol" 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;">&lt;t:if test="!symbol:tapestry.production-mode"&gt;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml; 
gutter: false; theme: Default" data-theme="Default">&lt;t:if 
test="!symbol:tapestry.production-mode"&gt;
   &lt;p&gt;WARNING: We're running in development mode (slower, and less 
secure)&lt;/p&gt;
 &lt;/t:if&gt;</pre>
 </div></div><h2 id="Symbols-SymbolResolution">Symbol Resolution</h2><p>Symbols 
are resolved by the <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/SymbolSource.html";>SymbolSource</a>
 service. The SymbolSource service checks against an ordered list of <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/services/SymbolProvider.html";>SymbolProvider</a>
 objects.</p><p>You may employ additional symbol providers by contributing to 
the SymbolSource service configuration, which is an ordered list of 
SymbolProviders.</p><p>By default, there are three providers:</p><h3 
id="Symbols-SystemPropertiesProvider">SystemProperties Provider</h3><p>The 
first provider allows JVM System Properties to provide symbol values. This 
allows the use of the <strong>java</strong> command's <strong>-D</strong> 
option to provide runtime overrides. This is most often used when testing code, 
rather than in pro
 duction. SystemProperties is always checked first.</p><h3 
id="Symbols-ApplicationDefaultsProvider">ApplicationDefaults 
Provider</h3><p>Values not found as System Properties are searched for in the 
ApplicationDefaults. This service, ApplicationDefaults, may be configured using 
a mapped configuration to provide values.</p><p>From the previous 
example:</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 void 
contributeApplicationDefaults(MappedConfiguration&lt;String, String&gt; 
configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public void 
contributeApplicationDefaults(MappedConfiguration&lt;String, String&gt; 
configuration)
   {
     configuration.add("some-service-id", "WackyCollaborator");
   }</pre>
 </div></div><h3 id="Symbols-FactoryDefaultsProvider">FactoryDefaults 
Provider</h3><p>This is the same as ApplicationDefaults, but checked only if a 
value is not satisfied by SystemProperties or 
ApplicationDefaults.</p><p>Libraries will typically set reasonable defaults as 
contributions to the FactoryDefaults service configuration. Individual 
applications may hard code overrides of those defaults using 
ApplicationDefaults. Individual developers may override even those defaults by 
setting JVM System Properties.</p><p>FactoryDefaults is always checked last 
when resolving symbol names to symbol values.</p><h2 
id="Symbols-RecursiveSymbols">Recursive Symbols</h2><p>It is possible and valid 
to define one symbol in terms of one or more other symbols.</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 void 
contributeFactoryDefaults(MappedConfiguration&lt;String, String&gt; 
configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public void 
contributeFactoryDefaults(MappedConfiguration&lt;String, String&gt; 
configuration)
   {
       configuration.add("report.url", 
"http://${report.host}:${report.port}/${report.path}";);
       configuration.add("report.host", "www.myreportsite.com");
@@ -198,7 +200,7 @@
       configuration.add("report.path", "/report.cgi");
   }</pre>
 </div></div><p>The ordinary default for <code>report.url</code> will be: 
<code><span 
class="nolink">http://www.myreportsite.com:80/report.cgi</span></code></p><p>However,
 this can be changed by making an overriding contribution to the 
ApplicationDefaults service configuration.</p><p>Tapestry checks that no symbol 
is directly or indirectly dependent on itself. For example, the following 
contribution is illegal:</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 void 
contributeApplicationDefaults(MappedConfiguration&lt;String, String&gt; 
configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public void 
contributeApplicationDefaults(MappedConfiguration&lt;String, String&gt; 
configuration)
   {
       configuration.add("report.path", "${report.url}/report.cgi");
   }</pre>

Modified: websites/production/tapestry/content/tapestry-for-jsf-users.html
==============================================================================
--- websites/production/tapestry/content/tapestry-for-jsf-users.html (original)
+++ websites/production/tapestry/content/tapestry-for-jsf-users.html Sun Apr 26 
21:22:55 2020
@@ -85,20 +85,22 @@
 
 
 
+
+
 <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="tapestry-for-jsf-users.html">Tapestry for 
JSF Users</a>
+                        <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="tapestry-tutorial.html">Tapestry Tutorial</a>
@@ -107,28 +109,28 @@
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="principles.html">Principles</a>
+                        <a  href="introduction.html">Introduction</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="getting-started.html">Getting Started</a>
+                        <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="introduction.html">Introduction</a>
+                        <a  href="principles.html">Principles</a>
                 
                         
                     </div>
@@ -137,7 +139,7 @@
 
 
 <p>Since almost all modern JSF applications use Facelets as their view 
technology, we assume the use of Facelets here when discussing JSF 
features.</p><p>JSF is a rich, mature web framework specification, and there 
are lots of smart people who use it productively. This guide isn't intended as 
a pro-versus-con comparison or as advocacy of any kind. Instead, it just 
attempts to make transitions between the two frameworks easier, regardless of 
the reason for doing so.</p><h2 
id="TapestryforJSFUsers-Side-by-sideComparison">Side-by-side 
Comparison</h2><p>JSF and Tapestry have a lot of superficial similarities, so 
the first steps in that transition are all about relating similar concepts, 
terms and components in your mind:</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Concepts &amp; Terminology</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><
 p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Java class associated with a page or 
component</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>"Backing 
Bean"</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>"<a  
href="component-classes.html">Component Class</a>"</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Component 
attributes/parameters</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"attributes"</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>"<a  
href="component-parameters.html">parameters</a>"</p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Common 
Attributes/Parameters</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>HTML Attribute used for invisible 
instrumentation</p></td><td colspan="1" rowspan="1" class
 ="confluenceTd"><p>jsfc="someComponentType"</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  
href="component-templates.html">t:type="someComponentType"</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>CSS "class" attribute 
name</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>styleClass</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>class</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Alternating "zebra" striped rows</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>rowclasses="class1,class2"</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>class="${cycle:class1,class2}" using <a  
class="external-link" 
href="https://wiki.apache.org/tapestry/Tapestry5HowToAddBindingPrefixCycle";>cycle
 binding prefix</a>, or with CSS: .rowClass:nth-child(even) {background-color: 
#e8e8e8;}</p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Output and Messages</p></th><th colspan="1
 " rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Escaped HTML from property</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>&lt;h:outputText 
value="myBean.myValue"/&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${myValue}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Raw HTML from property</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>#{myBean.myValue}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/OutputRaw.html";>&lt;t:outputRaw
 value="myValue"/&gt;</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Error messages</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:message&gt; and &lt;h:messages&gt;</p></td><td 
colspan="1" row
 span="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Error.html";>&lt;t:error&gt;</a>
 and <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Errors.html";>&lt;t:errors&gt;</a>
 (for forms) or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Alerts.html";>&lt;t:alerts&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Image display</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:graphicImage&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>use standard &lt;img&gt; tag, but see 
<a  href="assets.html">Assets</a><br clear="none"></em></p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Conditionals and 
Looping</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF</p></th><th colspa
 n="1" rowspan="1" class="confluenceTh"><p>Tapestry</p></th></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Render-time loop</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;ui:repeat&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Loop.html";>&lt;t:loop&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Compile-time loop</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;c:forEach&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Loop.html";>&lt;t:loop&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Conditional</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;c:if 
test="#{myBean.myValue}"&gt;</p></td><td colspan="1" rows
 pan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/If.html";>&lt;t:if
 test="myValue"&gt;</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Conditional</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;ui:fragment 
rendered="#{myBean.someCondition}"/&gt;...&lt;/ui:fragment&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/If.html";>&lt;t:if
 test="someCondition"&gt;...&lt;/t:if&gt;</a></p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Switch</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;c:choose&gt;&lt;c:when ... 
&gt;&lt;/c:choose&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>See <a  href="switching-cases.html">Switching 
Cases</a></p></td></tr><tr><td colspan="1" rowspan="1" c
 lass="confluenceTd"><p>Server-side comment</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;ui:remove&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  
href="component-templates.html">&lt;t:remove&gt;</a></p></td></tr><tr><th 
colspan="1" rowspan="1" class="confluenceTh"><p>Links and Buttons</p></th><th 
colspan="1" rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Navigational link</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>&lt;h:link 
outcome="nextpage.xhtml"/&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/PageLink.html";>&lt;t:pagelink
 page="nextpage"/&gt;</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Event-triggering link, without form submission</p></
 td><td colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/ActionLink.html";>&lt;t:actionLink&gt;</a>
 or <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/EventLink.html";>&lt;t:eventLink&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Form submission 
link</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:commandLink&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/LinkSubmit.html";>&lt;t:linkSubmit&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Form submission 
button</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>&lt
 ;h:commandButton&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Submit.html";>&lt;t:submit&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Link to Javascript 
file</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:outputScript&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>&lt;script&gt; or use @Import in 
component class</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Link to CSS file</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:outputStylesheet&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>&lt;style&gt; or use @Import in 
component class</em></p></td></tr><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Grids, Tables and Trees</p></th><th colspan="1" 
rowspan="1" class="confluenceTh"><p>JSF</p></th><th colspan="1" ro
 wspan="1" class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Tabular data in &lt;table&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:datatable&gt;</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Grid.html";>&lt;t:grid&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Table used for 
layout</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:panelGrid&gt; with 
&lt;h:panelGroup&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>use standard &lt;table&gt; 
tag</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Hierarchical tree</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>depends on component library</em></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" hr
 
ef="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Tree.html";>&lt;t:tree&gt;</a></p></td></tr><tr><th
 colspan="1" rowspan="1" class="confluenceTh"><p>Form 
Tags/Components</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry</p></th></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Form</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:form&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Form.html";>&lt;t:form&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Single-line text input 
field</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputText&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/curren
 
t/apidocs/org/apache/tapestry5/corelib/components/TextField.html">&lt;t:textField&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Password field</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputSecret&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/PasswordField.html";>&lt;t:passwordfield&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Select menu</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectOneMenu&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Select.html";>&lt;t:select&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Checkbox</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:
 selectBooleanCheckbox&gt;</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Checkbox.html";>&lt;t:checkbox&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Checkbox list</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectManyCheckbox&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Checklist.html";>&lt;t:checklist&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Radio button list</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectOneRadio&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/RadioGroup.html";>&lt;t:r
 adioGroup&gt;</a> with <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Radio.html";>&lt;t:radio&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Multiple select 
menu</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:selectManyListbox&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>not available</em> (but see Palette and 
Checklist)</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Hidden field</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&lt;h:inputHidden&gt;</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Hidden.html";>&lt;t:hidden&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>textarea tag</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:inputTextarea
 &gt;</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/TextArea.html";>&lt;t:textArea&gt;</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p>Label tag</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>&lt;h:outputLabel 
for="..."&gt;</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/Label.html";>&lt;t:label
 for="..."&gt;</a></p></td></tr></tbody></table></div><p>Some important 
notes:</p><ul><li>With Tapestry, you don't use the ${...} syntax with 
parameters of components. Just use a bare expression within the quotes. For 
example: &lt;t:textfield value="myProperty"&gt; instead of &lt;t:textfield 
value="${myProperty}"&gt;, because in the latter case the expression is 
converted to a read-only string before the te
 xtfield component gets it.</li></ul><h2 
id="TapestryforJSFUsers-HelloWorldComparison">Hello World 
Comparison</h2><p>Faces templates and Tapestry templates are superficially 
quite similar.</p><div class="sectionColumnWrapper"><div 
class="sectionMacro"><div class="sectionMacroRow"><div class="columnMacro"><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>JSF template 
(helloworld.xhtml)</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;html xmlns="http://www.w3.org/1999/xhtml";
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml; 
gutter: false; theme: Default" data-theme="Default">&lt;html 
xmlns="http://www.w3.org/1999/xhtml";
         xmlns:h="http://java.sun.com/jsf/html"&gt;
   &lt;h:body&gt;
     &lt;p&gt;&lt;h:outputText value="#{helloWorldBean.greeting} /&gt;&lt;/p&gt;
@@ -145,14 +147,14 @@
 &lt;/html&gt;
 </pre>
 </div></div></div><div class="columnMacro"><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Tapestry template 
(HelloWorld.tml)</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;html 
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"&gt;
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: xml; 
gutter: false; theme: Default" data-theme="Default">&lt;html 
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd"&gt;
   &lt;body&gt;
     &lt;p&gt;${greeting}&lt;/p&gt;
   &lt;/body&gt;
 &lt;/html&gt;
 </pre>
 </div></div></div></div></div></div><p>Though these are very similar, notice 
some differences:</p><ul><li>The #{...} syntax in JSF does not encode the 
underlying string, so you have to use the &lt;h:outputText&gt; tag if your data 
may contain HTML reserved characters such as &lt;, &gt;, or &amp;. In contrast, 
the ${...} syntax in Tapestry <strong>does</strong> encode the underlying 
string.</li><li>In JSF, backing beans are not necessarily related one-to-one 
with page templates. Often several templates use the same backing bean, and one 
template may reference multiple backing beans. In Tapestry, they are always 
related one-to-one, and therefore you don't have to specify which component 
class your ${...} expressions are referencing.</li></ul><div 
class="sectionColumnWrapper"><div class="sectionMacro"><div 
class="sectionMacroRow"><div class="columnMacro"><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>J
 SF Backing Bean (HelloWorldBean.java)</b></div><div class="codeContent 
panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@ManagedBean
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">@ManagedBean
 @RequestScoped
 public class HelloWorldBean {
     public String getGreeting() {
@@ -161,14 +163,14 @@ public class HelloWorldBean {
 }
 </pre>
 </div></div></div><div class="columnMacro"><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeHeader panelHeader pdl" 
style="border-bottom-width: 1px;"><b>Tapestry page class 
(HelloWorld.java)</b></div><div class="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">public class HelloWorld {
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class HelloWorld {
     public String getGreeting() {
         return "Hello, World!";
     }
 }
 </pre>
 </div></div></div></div></div></div><h2 
id="TapestryforJSFUsers-Expressionsintemplates">Expressions in 
templates</h2><p>JSF uses the Unified Expression Language with the #{...} or 
${...} syntax for accessing Backing Bean properties. For its part, Tapestry 
uses the ${...} syntax with a similar but intentionally limited expression 
language called <a  href="property-expressions.html">Property Expressions</a>. 
Both allow easy access to properties via the usual JavaBean conventions, but 
with Tapestry you don't have to specify which class the expression starts at 
(because it always starts at the component class corresponding to the 
template). Some comparisons:</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&#160;</p></td><th colspan="1" rowspan="1" 
class="confluenceTh"><p>JSF Syntax</p></th><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry Syntax</p></th></tr><tr><td colspan="1" 
rowspan="1" class="conflue
 nceTd"><p>Property (calls getEmployeeName() or setEmployeeName())</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>#{employeeBean.employeeName}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${employeeName}</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Boolean property (calls 
isHourly() or setHourly())</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{employeeBean.hourly}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${hourly}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Property chain</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>#{employeeBean.address.street}</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>${address.street}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Null-safe property chain</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>#{employeeBean.address.street}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd
 "><p>${address?.street}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>5th element in a List</p></td><td colspan="1" 
rowspan="1" 
class="confluenceTd"><p>#{employeeBean.employees[5].name}</p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>${employees.get(5).name}</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Negation</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p>#{! 
employeeBean.hourly}</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${! hourly}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>Arithmetic &amp; relational 
operators</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>+-*/% div 
mod</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Relational operators</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>== != ne &lt; lt &gt; gt &lt;= le &gt;= 
ge</p></td><td
  colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Ternary operator</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{myBean.foo &lt; 0 ? 'bar' : 'baz'}</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
available</em></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Method calling</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>#{myBean.employees.size()}</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${employees.size()}</p></td></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p>Iterated Range</p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><em>not 
avaialble</em></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${1..10}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Iterated Range (calculated)</p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><em>not avaialb
 le</em></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>${1..groupList.size()}</p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>List</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>not available</em></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${ [ <a  class="external-link" 
href="http://user.name"; rel="nofollow">user.name</a>, user.email, user.phone ] 
}</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>Map</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><em>not available</em></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p>${ { 'id':'4039','type':'hourly' } 
}</p></td></tr></tbody></table></div><p>Features shown as <em>not 
available</em> above are absent by design, because (in both Tapestry and JSF) 
it is considered best to keep complex logic in the component class rather than 
in the template.</p><h2 
id="TapestryforJSFUsers-EventHandling&amp;PageNavigation">Event Handling &amp; 
 Page Navigation</h2><h3 id="TapestryforJSFUsers-Eventhandling">Event 
handling</h3><p>In JSF, you specify the event via the <code>action</code> 
parameter (for example, &lt;h:commandButton value="Submit" 
action="employeeBean.saveChanges"&gt;). For Tapestry, event handler methods are 
found by method naming conventions (onSomeEvent() or by method annotations 
(@Event), based on a combination of the "t:id" attribute and event name, and 
the action name used depends on the component. For example, the 
"&lt;t:actionlink&gt;" component in Tapestry emits an "action" event when 
clicked, and you handle that event in your "onAction()" method.</p><h2 
id="TapestryforJSFUsers-Validation">Validation</h2><p>Tapestry applications can 
use JSR 303 Bean Validation annotations that JSF users should be familiar 
with:</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 Employee {
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">public class Employee {
     @Validate("required,minlength=2,maxlength=100")
     private String lastName;
     @NotNull @Email private String email;

Modified: 
websites/production/tapestry/content/tapestry-inversion-of-control-faq.html
==============================================================================
--- websites/production/tapestry/content/tapestry-inversion-of-control-faq.html 
(original)
+++ websites/production/tapestry/content/tapestry-inversion-of-control-faq.html 
Sun Apr 26 21:22:55 2020
@@ -78,11 +78,11 @@
 
       <div id="content">
                 <div id="ConfluenceContent"><h1 
id="TapestryInversionofControlFAQ-TapestryInversionofControlContainer">Tapestry 
Inversion of Control Container</h1><p>Main article: <a  
href="tapestry-inversion-of-control-faq.html">Tapestry IoC</a></p><h2 
id="TapestryInversionofControlFAQ-Contents">Contents</h2><p><style 
type="text/css">/*<![CDATA[*/
-div.rbtoc1587536393230 {padding: 0px;}
-div.rbtoc1587536393230 ul {list-style: disc;margin-left: 0px;}
-div.rbtoc1587536393230 li {margin-left: 0px;padding-left: 0px;}
+div.rbtoc1587935991602 {padding: 0px;}
+div.rbtoc1587935991602 ul {list-style: disc;margin-left: 0px;}
+div.rbtoc1587935991602 li {margin-left: 0px;padding-left: 0px;}
 
-/*]]>*/</style></p><div class="toc-macro rbtoc1587536393230">
+/*]]>*/</style></p><div class="toc-macro rbtoc1587935991602">
 <ul class="toc-indentation"><li><a  
href="#TapestryInversionofControlFAQ-WhydoIneedtodefineaninterfaceformyservices?Whycan'tIjustusetheclassitself?">Why
 do I need to define an interface for my services? Why can't I just use the 
class itself?</a></li><li><a  
href="#TapestryInversionofControlFAQ-Myservicestartsathread;howdoIknowwhentheapplicationisshuttingdown,tostopthatthread?">My
 service starts a thread; how do I know when the application is shutting down, 
to stop that thread?</a></li><li><a  
href="#TapestryInversionofControlFAQ-HowdoImakemyservicestartupwiththerestoftheapplication,ratherthanlazily?">How
 do I make my service startup with the rest of the application, rather than 
lazily?</a></li></ul>
 </div><p>&#160;</p><div class="aui-label" style="float:right" title="Related 
Articles">
 

Modified: websites/production/tapestry/content/tapestry-ioc-configuration.html
==============================================================================
--- websites/production/tapestry/content/tapestry-ioc-configuration.html 
(original)
+++ websites/production/tapestry/content/tapestry-ioc-configuration.html Sun 
Apr 26 21:22:55 2020
@@ -84,38 +84,40 @@
 
 
 
+
+
 <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>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  
href="application-module-class-cheat-sheet.html">Application Module Class Cheat 
Sheet</a>
+                        <a  href="response-compression.html">Response 
Compression</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  
href="ioc-cookbook-service-configurations.html">IoC cookbook - Service 
Configurations</a>
+                        <a  href="symbols.html">Symbols</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="symbols.html">Symbols</a>
+                        <a  
href="application-module-class-cheat-sheet.html">Application Module Class Cheat 
Sheet</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="tapestry-ioc-configuration.html">Tapestry 
IoC Configuration</a>
@@ -124,16 +126,16 @@
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
-                        <a  href="response-compression.html">Response 
Compression</a>
+                        <a  
href="ioc-cookbook-service-configurations.html">IoC cookbook - Service 
Configurations</a>
                 
                         
                     </div>
     </li><li>
         <div>
-                <span class="icon aui-icon aui-icon-small 
aui-iconfont-page-default" title="Page">Page:</span>        </div>
+                <span class="icon aui-icon content-type-page" 
title="Page">Page:</span>        </div>
 
         <div class="details">
                         <a  href="configuration.html">Configuration</a>
@@ -145,18 +147,18 @@
 
 
 <p>One of the key concepts in Tapestry IoC is <em>distributed 
configuration</em>. The <em>distributed</em> part refers to the fact that 
<em>any module</em> may configure a service. Distributed configuration is the 
key feature of Tapestry IoC that supports extensibility and 
modularity.</p><p>Modules configure a service by <em>contributing</em> to 
service configurations. This may seem esoteric but is really pretty simple. 
We'll explain with an example.</p><p>Let's say you've written a bunch of 
different services, each of which does something specific for a particular type 
of file (identified by the file's extension), and each implements the same 
interface, which we'll call FileServicer. And now let's say you need a central 
service that selects the one of your FileServicer implementations based on a 
given file extension. You start by providing a <a  
href="defining-tapestry-ioc-services.html">service builder method</a>:</p><div 
class="code panel pdl" style="border-width: 1px;"><div clas
 s="codeContent panelContent pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  public static FileServiceDispatcher 
buildFileServicerDispatcher(Map&lt;String,FileServicer&gt; contributions)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static 
FileServiceDispatcher 
buildFileServicerDispatcher(Map&lt;String,FileServicer&gt; contributions)
   {
     return new FileServiceDispatcherImpl(contributions);
   } </pre>
 </div></div><p>In order to provide a value for the contribution parameter, 
Tapestry will <em>collect</em> contributions from service contribution methods. 
It will ensure that the keys and values match the generic types shown (String 
for the key, FileServicer for the value). The map will be assembled and passed 
into the service builder method, and from there, into the 
FileServiceDispatcherImpl constructor.</p><p>So where do the values come from? 
Your service contributor methods, methods whose names start with 
"contribute":</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 static void 
contributeFileServicerDispatcher(MappedConfiguration&lt;String,FileServicer&gt; 
configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static void 
contributeFileServicerDispatcher(MappedConfiguration&lt;String,FileServicer&gt; 
configuration)
   {
     configuration.add("txt", new TextFileServicer());
     configuration.add("pdf", new PDFFileServicer());
   }  </pre>
 </div></div><p>Or, instead of instantiating those services ourselves, we could 
<a  href="injection-in-detail.html">inject</a> them:</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 static void 
contributeFileServicerDispatcher(MappedConfiguration&lt;String,FileServicer&gt; 
configuration,
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static void 
contributeFileServicerDispatcher(MappedConfiguration&lt;String,FileServicer&gt; 
configuration,
   
     @InjectService("TextFileServicer") FileServicer textFileServicer,
     @InjectService("PDFFileServicer") FileServicer pdfFileServicer)
@@ -165,7 +167,7 @@
     configuration.add("pdf", pdfFileServicer);
   }  </pre>
 </div></div><p>The <strong>extensibility</strong> comes from the fact that 
multiple modules may all contribute to the same service configuration:</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 static void 
contributeFileServicerDispatcher(MappedConfiguration&lt;String,FileServicer&gt; 
configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static void 
contributeFileServicerDispatcher(MappedConfiguration&lt;String,FileServicer&gt; 
configuration)
   {
     configuration.add("doc", new WordFileServicer());
     configuration.add("ppt", new PowerPointFileServicer());
@@ -177,7 +179,7 @@
 
 
 </div>If you prefer annotations over naming conventions you can use the @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Contribute.html";>Contribute</a>
 annotation. As of version 5.2 this annotation that may be placed on a 
contributor method of a module instead of starting the methods name with 
"contribute". The value of the annotation is the type of the service to 
contribute into.<p>The primary reasons to use @Contribute and marker 
annotations is twofold:</p><ul><li>There is no longer a linkage between the 
contribution method name and the service id, which is much more refactoring 
safe: if you change the service interface name, or the ID of the service, your 
method will still be invoked when using @Contribute.</li></ul><ul><li>It makes 
it much easier for an <span class="confluence-link">override</span> of the 
service to get the configuration intended for the original 
service.</li></ul><p>The following example is an annotat
 ion-based alternative for the contribution method above.</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;">@Contribute(FileServiceDispatcher.class)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" 
data-theme="Default">@Contribute(FileServiceDispatcher.class)
 public static void 
arbitraryMethodName(MappedConfiguration&lt;String,FileServicer&gt; 
configuration)
 {
     configuration.add("doc", new WordFileServicer());
@@ -185,7 +187,7 @@ public static void arbitraryMethodName(M
 }  
 </pre>
 </div></div><p>If you have several implementations of a service interface, you 
have to disambiguate the services. For this purpose the marker annotations 
should be placed on the contributor method.</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;">@Contribute(FileServiceDispatcher.class)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" 
data-theme="Default">@Contribute(FileServiceDispatcher.class)
 @Red @Blue
 public static void 
arbitraryMethodName(MappedConfiguration&lt;String,FileServicer&gt; 
configuration)
 {
@@ -194,7 +196,7 @@ public static void arbitraryMethodName(M
 }
 </pre>
 </div></div><p>In this example, the method will only be invoked when 
constructing a service configuration where the service itself has both the Red 
and Blue marker annotations. Tapestry knows which annotations are marker 
annotations, and which marker annotations apply to the service, via the @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Marker.html";>Marker</a>
 annotation on the service implementation.</p><p>If the special @<a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Local.html";>Local</a>
 annotation is present, then the contribution is made only to the configuration 
of a service being constructed in the same module.</p><p>Note that it 
<em>is</em> possible for the same contribution method to be invoked to 
contribute to the configuration of multiple different services.</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelConten
 t pdl">
-<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Contribute(FileServiceDispatcher.class)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  
@Contribute(FileServiceDispatcher.class)
   @Local
   public static void 
arbitraryMethodName(MappedConfiguration&lt;String,FileServicer&gt; 
configuration)
   {
@@ -203,7 +205,7 @@ public static void arbitraryMethodName(M
   }  
 </pre>
 </div></div><h1 id="TapestryIoCConfiguration-ConfigurationTypes">Configuration 
Types</h1><p>There are three different styles of configurations (with matching 
contributions):</p><ul><li><strong>Unordered Collection</strong> &#8211; 
Contributions are simply added in and order is not 
important.</li><li><strong>Ordered List</strong> &#8211; Contributions are 
provided as an ordered list. Contributions must establish the order by giving 
each contributed object a unique id, by establishing forward and backward 
dependencies between the values.</li><li><strong>Map</strong> &#8211; 
Contributions provide unique keys and corresponding values.</li></ul><h2 
id="TapestryIoCConfiguration-UnorderedCollection">Unordered Collection</h2><p>A 
service builder method can collect an unordered list of values by defining a 
parameter of type java.util.Collection. Further, you should parameterize the 
type of collection. Tapestry will identify the parameterized type and ensure 
that all contributions match.</p><
 p>One thing to remember is that the order in which contributions occur is 
unspecified. There will be a possibly large number of modules, each having zero 
or more methods that contribute into the service. The order in which these 
methods are invoked is unknown.</p><p>For example, here's a kind of Startup 
service that needs some Runnable objects. It doesn't care what order the 
Runnable objects are executed in.</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 static Runnable buildStartup(final 
Collection&lt;Runnable&gt; configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static Runnable 
buildStartup(final Collection&lt;Runnable&gt; configuration)
   {
     return new Runnable()
     {
@@ -215,13 +217,13 @@ public static void arbitraryMethodName(M
     };
   }  </pre>
 </div></div><p>Here we don't even need a separate class for the 
implementation, we use an inner class for the implementation. The point is, the 
configuration is provided to the builder method, which passes it along to the 
implementation of the service.</p><p>On the contribution side, a service 
contribution method sees a <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/Configuration.html";>Configuration</a>
 object:</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 static void 
contributeStartup(Configuration&lt;Runnable&gt; configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static void 
contributeStartup(Configuration&lt;Runnable&gt; configuration)
   {
     configuration.add(new JMSStartup());
     configuration.add(new FileSystemStartup());
   }    </pre>
 </div></div><p>The Configuration interface defines just a single method: 
<code>add()</code>. This is very intentional: the only thing you can do is add 
new items. If we passed in a Collection, you might be tempted to check it for 
values, or remove them ... but that flies in the face of the fact that the 
order of execution of these service contribution methods is entirely 
unknown.</p><p>For readability, we've parameterized the configuration parameter 
of the method, constraining it to instances of java.lang.Runnable, so as to 
match the corresponding parameter. This is optional, but often very helpful. In 
any case, attempting to contribute an object that doesn't extend or implement 
the type (Runnable) will result in a runtime warning (and the value will be 
ignored).</p><p>Tapestry supports only this simple form of parameterized types. 
Java generics supports a wider form, "wildcards", that Tapestry doesn't 
understand.</p><p><span class="confluence-anchor-link" 
id="TapestryIoCConfigurati
 on-Ordered_List"></span></p><h2 
id="TapestryIoCConfiguration-OrderedList">Ordered List</h2><p>Ordered lists are 
much more common. With an ordered list, the contributions are sorted into a 
proper order before being provided to the service builder method.</p><p>Again, 
the order in which service contribution methods are invoked is unknown. 
Therefore, the order in which objects are added to the configuration is not 
known. Instead, we enforce an order on the items <em>after</em> all the 
contributions have been added. As with <a  
href="tapestry-ioc-decorators.html">service decorators</a>, we set the order by 
giving each contributed object a unique id, and identifying (by id) which items 
must preceded it in the list, and which must follow.</p><p>So, if we changed 
our Startup service to require a specific order for startup:</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 static Runnable buildStartup(final 
List&lt;Runnable&gt; configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static Runnable 
buildStartup(final List&lt;Runnable&gt; configuration)
   {
     return new Runnable()
     {
@@ -233,7 +235,7 @@ public static void arbitraryMethodName(M
     };
   }  </pre>
 </div></div><p>Notice that the service builder method is shielded from the 
details of how the items are ordered. It doesn't have to know about IDs and 
pre- and post-requisites. By using a parameter type of List, we've triggered 
Tapestry to collect all the ordering information.</p><p>For our service 
contribution methods, we must provide a parameter of type <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/OrderedConfiguration.html";>OrderedConfiguration</a>:</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 static void 
contributeStartup(OrderedConfiguration&lt;Runnable&gt; configuration)
+<pre class="syntaxhighlighter-pre" data-syntaxhighlighter-params="brush: java; 
gutter: false; theme: Default" data-theme="Default">  public static void 
contributeStartup(OrderedConfiguration&lt;Runnable&gt; configuration)
   {
     configuration.add("JMS", new JMSStartup());
     configuration.add("FileSystem", new FileSystemStartup(), 
"after:CacheSetup");


Reply via email to