tapestry-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From build...@apache.org
Subject svn commit: r956226 [7/34] - in /websites/production/tapestry/content: ./ 2010/10/11/ 2010/10/31/ 2010/11/18/ 2010/11/19/ 2010/12/16/ 2010/12/17/ 2011/01/10/ 2011/03/29/ 2011/06/13/ 2011/06/24/ 2011/06/29/ 2011/07/29/ 2011/08/16/ 2011/08/27/ 2011/10/31...
Date Sat, 27 Jun 2015 21:21:05 GMT
Modified: websites/production/tapestry/content/component-events.html
==============================================================================
--- websites/production/tapestry/content/component-events.html (original)
+++ websites/production/tapestry/content/component-events.html Sat Jun 27 21:21:02 2015
@@ -27,16 +27,6 @@
   </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 type="text/javascript">
-  SyntaxHighlighter.defaults['toolbar'] = false;
-  SyntaxHighlighter.all();
-  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -55,7 +45,7 @@
   <input type="submit" value="Search">
 </form>
 
-</div><div class="emblem" style="float:left"><p><a shape="rect" href="index.html"><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"></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Component Events</h1></div></div>
+</div><div class="emblem" style="float:left"><p><a shape="rect" 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">Component Events</h1></div></div>
 <div class="clearer"></div>
 </div>
 
@@ -68,64 +58,8 @@
 
 <div id="content">
 <div id="ConfluenceContent"><h1 id="ComponentEvents-ComponentEvents">Component Events</h1><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
-<h3>Related Articles</h3>
-<ul class="content-by-label"><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="component-events-faq.html">Component Events FAQ</a>
-                    
-                
-                            </div>
-        </li><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="request-processing.html">Request Processing</a>
-                    
-                
-                            </div>
-        </li><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="page-life-cycle.html">Page Life Cycle</a>
-                    
-                
-                            </div>
-        </li><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="component-rendering.html">Component Rendering</a>
-                    
-                
-                            </div>
-        </li><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="page-navigation.html">Page Navigation</a>
-                    
-                
-                            </div>
-        </li><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="component-events.html">Component Events</a>
-                    
-                
-                            </div>
-        </li></ul>
-</div><p><strong>Component events</strong> are Tapestry's way of conveying a user's interactions with the web page, such as clicking links and submitting forms, to designated methods in your page and component classes. When a component event occurs, Tapestry calls the event handler method you've provided, if any, in the containing component's class.</p><p>Let's review a simple example. Here's a portion of the template for a page (let's call it "Chooser") that lets the user choose a number between 1 and 10:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[&lt;p&gt; Choose a number from 1 to 10:
+<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div><p><strong>Component events</strong> are Tapestry's way of conveying a user's interactions with the web page, such as clicking links and submitting forms, to designated methods in your page and component classes. When a component event occurs, Tapestry calls the event handler method you've provided, if any, in the containing component's class.</p><p>Let's review a simple example. Here's a portion of the template for a page (let's call it "Chooser") that lets the user choose a number between 1 and 10:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[&lt;p&gt; Choose a number from 1 to 10:
 
     &lt;t:count end=&quot;10&quot; value=&quot;index&quot;&gt;
         &lt;a t:id=&quot;select&quot; t:type=&quot;actionlink&quot; context=&quot;index&quot;&gt;${index}&lt;/t:comp&gt;
@@ -133,7 +67,7 @@
 &lt;/p&gt;
 ]]></script>
 </div></div><p>Notice that Chooser.tml contains an ActionLink component. When rendered on the page, the ActionLink component creates a component event request URL, with the event type set to "action". In this case the URL might look like <code><a shape="rect" class="external-link" href="http://localhost:8080/chooser.select/3" >http://localhost:8080/chooser.select/3</a></code></p><p>This URL identifies the page that contains the component ("chooser"), the type of event (unless it is "action", the default and most common event type), the id of the component within the page ("select"), plus the additional context value ("3"). <em>Additional context values, if any, are appended to the path.</em></p><p>There's no direct mapping from URL to a piece of code. Instead, when the user clicks on the link, the ActionLink component emits events. And then Tapestry ensures that the correct bit of code (your event handler method, see below) gets invoked for those events.</p><p>This demonstrates a cr
 itical difference between Tapestry and a more traditional, action oriented framework. The URL doesn't say what happens when the link is clicked, it identifies <em>which component is responsible</em> when the link is clicked.</p><p>Often, a navigation request (originating with the user) will spawn a number of flow-of-control requests. For example, an action event will trigger a form component, which will then emit notification events to announce when the form submission is about to be processed, and whether it was successful or not, and those event could be further handled by the page component.</p><h1 id="ComponentEvents-EventHandlerMethods">Event Handler Methods</h1><p>When a component event occurs, Tapestry invokes any event handler methods that you have identified for that event. You can identify your event handler methods via a naming convention (see Method Naming Convention below), or via the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidoc
 s/org/apache/tapestry5/annotations/OnEvent.html">OnEvent</a> annotation.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @OnEvent(component = &quot;select&quot;)
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @OnEvent(component = &quot;select&quot;)
   void valueChosen(int value)
   {
     this.value = value;
@@ -141,44 +75,25 @@
 ]]></script>
 </div></div><p>Tapestry does two things here:</p><ul><li>Because of the annotation, it identifies method valueChosen() as the method to invoke.</li><li>When the link is clicked, it converts the context value from a string to an integer and passes it into the method.</li></ul>
 
-    <div class="aui-message hint shadowed information-macro">
-                    <p class="title">Added in 5.3</p>
-                            <span class="aui-icon icon-hint">Icon</span>
-                <div class="message-content">
-                            
-
-                    </div>
-    </div>
-
+<div class="confluence-information-macro confluence-information-macro-information"><p class="title">Added in 5.3</p><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
+</div></div>
 <div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;">
 <p>Starting in release 5.3, Tapestry will validate that the component, if any, identified for the event handler method actually exists in the containing component's template. This helps with typos in annotations (or in the naming conventions identified below).</p>
 </div><p>In the above example, the valueChosen() method will be invoked when the default event, "action", occurs in the <code>select</code> component (and has at least one context value).</p><p>For some components, more than one type of event can occur, in which case you will want to be more specific:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @OnEvent(value = &quot;action&quot;, component = &quot;select&quot;)
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @OnEvent(value = &quot;action&quot;, component = &quot;select&quot;)
   void valueChosen(int value)
   {
     this.value = value;
   }
 ]]></script>
-</div></div><p>The <code>value</code> attribute of the OnEvent annotation is the name of the event to match. The default event type is "action"; the ActionLink and Form components each use this event type. Alternatively, we could have used an EventLink component, in which case the name of the event is determined by the element's ID, rather than being "action".</p><p>If you omit the <code>component</code> part of the OnEvent annotation, then you'll receive notifications from <em>all</em> contained components, possibly including nested components (due to event bubbling).</p>    <div class="aui-message success shadowed information-macro">
-                            <span class="aui-icon icon-success">Icon</span>
-                <div class="message-content">
-                            <p>You should usually specify exactly which component(s) you wish to receive events from. Using @OnEvent on a method and not specifying a specific component id means that the method will be invoked for events from <em>any</em> component.</p>
-                    </div>
-    </div>
-<p>Event handler methods are normally given package-private visibility, to support testing, although technically they may have any visibility (even private).</p><p>A single event handler method may receive notifications from many different components.</p><p>As elsewhere, the comparison of event type and component id is case-insensitive.</p><h2 id="ComponentEvents-MethodNamingConvention">Method Naming Convention</h2><p>As an alternative to the use of annotations, you may name your event handling methods following a certain convention, and Tapestry will find and invoke your methods just as if they were annotated.</p><p>This style of event handler methods start with the prefix "on", followed by the name of the action. You may then continue by adding "From" and a capitalized component id (remember that Tapestry is case insensitive about event names and component ids). So, for example, a method named onActionFromSelect(), if it exists, is invoked whenever an <code>Action</code> event is 
 emitted by the <code>select</code> component.</p><p>The previous example may be rewritten as:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  void onActionFromSelect(int value)
+</div></div><p>The <code>value</code> attribute of the OnEvent annotation is the name of the event to match. The default event type is "action"; the ActionLink and Form components each use this event type. Alternatively, we could have used an EventLink component, in which case the name of the event is determined by the element's ID, rather than being "action".</p><p>If you omit the <code>component</code> part of the OnEvent annotation, then you'll receive notifications from <em>all</em> contained components, possibly including nested components (due to event bubbling).</p><div class="confluence-information-macro confluence-information-macro-tip"><span class="aui-icon aui-icon-small aui-iconfont-approve confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>You should usually specify exactly which component(s) you wish to receive events from. Using @OnEvent on a method and not specifying a specific component id means that the method will be invoke
 d for events from <em>any</em> component.</p></div></div><p>Event handler methods are normally given package-private visibility, to support testing, although technically they may have any visibility (even private).</p><p>A single event handler method may receive notifications from many different components.</p><p>As elsewhere, the comparison of event type and component id is case-insensitive.</p><h2 id="ComponentEvents-MethodNamingConvention">Method Naming Convention</h2><p>As an alternative to the use of annotations, you may name your event handling methods following a certain convention, and Tapestry will find and invoke your methods just as if they were annotated.</p><p>This style of event handler methods start with the prefix "on", followed by the name of the action. You may then continue by adding "From" and a capitalized component id (remember that Tapestry is case insensitive about event names and component ids). So, for example, a method named onActionFromSelect(), if it exi
 sts, is invoked whenever an <code>Action</code> event is emitted by the <code>select</code> component.</p><p>The previous example may be rewritten as:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  void onActionFromSelect(int value)
   {
     this.value = value;
   }
 ]]></script>
-</div></div>    <div class="aui-message hint shadowed information-macro">
-                            <span class="aui-icon icon-hint">Icon</span>
-                <div class="message-content">
-                            <p>Note from Howard: I've found that I prefer the naming convention approach, and reserve the annotation just for situations that don't otherwise fit.</p>
-                    </div>
-    </div>
-<h2 id="ComponentEvents-MethodReturnValues">Method Return Values</h2><p>Main Article: <a shape="rect" href="page-navigation.html">Page Navigation</a></p><p>For page navigation events (originating in components such as EventLink, ActionLink and Form), the value returned from an event handler method determines how Tapestry will render a response.</p><ul><li><strong>Null</strong>: For no value, or null, the current page (the page containing the component) will render the response.</li><li><strong>Page</strong>: For the name of a page, or a page class or page instance, a render request URL will be constructed and sent to the client as a redirect to that page.</li><li><strong>URL</strong>: For a java.net.URL, a redirect will be sent to the client. (In Tapestry 5.3.x and earlier, this only works for non-Ajax requests.)</li><li><strong>Zone body</strong>: In the case of an Ajax request to update a zone, the component event handler will return the new zone body, typically via an injected co
 mponent or block.</li><li><strong>HttpError</strong>: For an <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/HttpError.html">HttpError</a>, an error response is sent to the client.</li><li><strong>Link</strong>: For a <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Link.html">Link</a>, a redirect is sent to the client.</li><li><strong>Stream</strong>: For a <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/StreamResponse.html">StreamResponse</a>, a stream of data is sent to the client</li></ul><p>See <a shape="rect" href="page-navigation.html">Page Navigation</a> for more details.</p><h2 id="ComponentEvents-MultipleMethodMatches">Multiple Method Matches</h2><p>In some cases, there may be multiple event handler methods matching a single event. In that case, Tapestry invokes them in the following orde
 r:</p><ul><li>Base class methods before sub-class methods.</li><li>Matching methods within a class in alphabetical order.</li><li>For a single method name with multiple overrides, by number of parameters, descending.</li></ul><p>Of course, ordinarily would you <em>not</em> want to create more than one method to handle an event.</p><p>When a sub-class overrides an event handler method of a base class, the event handler method is only invoked once, along with any other base class methods. The subclass can change the <em>implementation</em> of the base class method via an override, but can't change the <em>timing</em> of when that method is invoked. See <a shape="rect" class="external-link" href="https://issues.apache.org/jira/browse/TAP5-51">issue TAP5-51</a>.</p><h1 id="ComponentEvents-EventContext">Event Context</h1><p>The context values (the context parameter to the EventLink or ActionLink component) can be any object. However, only a simple conversion to string occurs. (This is in
  contrast to Tapestry 4, which had an elaborate type mechanism with the odd name "DataSqueezer".)</p><p>Again, whatever your value is (string, number, date), it is converted into a plain string. This results in a more readable URL.</p><p>If you have multiple context values (by binding a list or array of objects to the <em>context</em> parameter of the EventLink or ActionLink), then each one, in order, will be added to the URL.</p><p>When an event handler method is invoked, the strings are converted back into values, or even objects. A <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ValueEncoder.html">ValueEncoder</a> is used to convert between client-side strings and server-side objects. The <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ValueEncoderSource.html">ValueEncoderSource</a> service provides the necessary value encoders.</p><p>As shown in the ex
 ample above, most of the parameters passed to the event handler method are derived from the values provided in the event context. Each successive method parameter matches against a value provided in the event context (the context parameter of the ActionLink component; though many components have a similar context parameter).</p><p>In some cases, it is desirable to have direct access to the context (for example, to adapt to cases where there are a variable number of context values). The context values may be passed to an event handler method as parameter of the following types:</p><ul><li><a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/EventContext.html">EventContext</a></li><li>Object[]</li><li>List&lt;Object&gt;</li></ul><p>The latter two should be avoided, they may be removed in a future release. In all of these cases, the context parameter acts as a freebie; it doesn't match against a context value as it represents <em>a
 ll</em> context values.</p><h2 id="ComponentEvents-AccessingRequestQueryParameters">Accessing Request Query Parameters</h2><p>A parameter may be annotated with the @RequestParameter annotation; this allows a query parameter to be extracted from the request, converted to the correct type, and passed to the method. Again, this doesn't count against the event context values.</p><h2 id="ComponentEvents-MethodMatching">Method Matching</h2><p>An event handler method will only be invoked <em>if the context contains at least as many values as the method has parameters</em>. Methods with too many parameters will be silently skipped.</p><p>Tapestry will silently skip over a method if there are insufficient values in the context to satisfy the number of parameters requested.</p><p>EventContext parameters, and parameters annotated with @RequestParameter, do not count against this limit.</p><h2 id="ComponentEvents-MethodOrdering">Method Ordering</h2><p>When multiple methods match within the same
  class, Tapestry will invoke them in ascending alphabetical order. When there are multiple overrides of the same method name, Tapestry invokes them in descending order by number of parameters. In general, these situations don't happen ... in most cases, only a single method is required to handle a specific event form a specific component.</p><p>An event handler method may return the value <code>true</code> to indicate that the event has been handled; this immediately stops the search for additional methods in the same class (or in base classes) or in containing components.</p><h1 id="ComponentEvents-EventBubbling">Event Bubbling</h1><p>The event will bubble up the hierarchy, until it is aborted. The event is aborted when an event handler method returns a non-null value.</p><p>Returning a boolean value from an event handler method is special. Returning true will abort the event with no result; use this when the event is fully handled without a return value and no further event handle
 rs (in the same component, or in containing components) should be invoked.</p><p>Returning false is the same as returning null; event processing will continue to look for more event handlers, in the same component or its parent.</p><p>When an event bubbles up from a component to its container, the origin of the event is changed to be the component. For example, a Form component inside a BeanEditForm component may fire a success event. The page containing the BeanEditForm may listen for that event, but it will be from the BeanEditForm component (which makes sense, because the id of the Form inside the BeanEditForm is part of the BeanEditForm's implementation, not its public interface).</p><h1 id="ComponentEvents-EventMethodExceptions">Event Method Exceptions</h1><p>Event methods are allowed to throw any exception (not just runtime exceptions). If an event method does throw an exception, Tapestry will catch the thrown exception and ultimately display the exception report page.</p><p>I
 n other words, there's no need to do this:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  void onActionFromRunQuery()
+</div></div><div class="confluence-information-macro confluence-information-macro-information"><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>Note from Howard: I've found that I prefer the naming convention approach, and reserve the annotation just for situations that don't otherwise fit.</p></div></div><h2 id="ComponentEvents-MethodReturnValues">Method Return Values</h2><p>Main Article: <a shape="rect" href="page-navigation.html">Page Navigation</a></p><p>For page navigation events (originating in components such as EventLink, ActionLink and Form), the value returned from an event handler method determines how Tapestry will render a response.</p><ul><li><strong>Null</strong>: For no value, or null, the current page (the page containing the component) will render the response.</li><li><strong>Page</strong>: For the name of a page, or a page class or page instance, a render request URL
  will be constructed and sent to the client as a redirect to that page.</li><li><strong>URL</strong>: For a java.net.URL, a redirect will be sent to the client. (In Tapestry 5.3.x and earlier, this only works for non-Ajax requests.)</li><li><strong>Zone body</strong>: In the case of an Ajax request to update a zone, the component event handler will return the new zone body, typically via an injected component or block.</li><li><strong>HttpError</strong>: For an <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/HttpError.html">HttpError</a>, an error response is sent to the client.</li><li><strong>Link</strong>: For a <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/Link.html">Link</a>, a redirect is sent to the client.</li><li><strong>Stream</strong>: For a <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapes
 try5/StreamResponse.html">StreamResponse</a>, a stream of data is sent to the client</li></ul><p>See <a shape="rect" href="page-navigation.html">Page Navigation</a> for more details.</p><h2 id="ComponentEvents-MultipleMethodMatches">Multiple Method Matches</h2><p>In some cases, there may be multiple event handler methods matching a single event. In that case, Tapestry invokes them in the following order:</p><ul><li>Base class methods before sub-class methods.</li><li>Matching methods within a class in alphabetical order.</li><li>For a single method name with multiple overrides, by number of parameters, descending.</li></ul><p>Of course, ordinarily would you <em>not</em> want to create more than one method to handle an event.</p><p>When a sub-class overrides an event handler method of a base class, the event handler method is only invoked once, along with any other base class methods. The subclass can change the <em>implementation</em> of the base class method via an override, but ca
 n't change the <em>timing</em> of when that method is invoked. See <a shape="rect" class="external-link" href="https://issues.apache.org/jira/browse/TAP5-51">issue TAP5-51</a>.</p><h1 id="ComponentEvents-EventContext">Event Context</h1><p>The context values (the context parameter to the EventLink or ActionLink component) can be any object. However, only a simple conversion to string occurs. (This is in contrast to Tapestry 4, which had an elaborate type mechanism with the odd name "DataSqueezer".)</p><p>Again, whatever your value is (string, number, date), it is converted into a plain string. This results in a more readable URL.</p><p>If you have multiple context values (by binding a list or array of objects to the <em>context</em> parameter of the EventLink or ActionLink), then each one, in order, will be added to the URL.</p><p>When an event handler method is invoked, the strings are converted back into values, or even objects. A <a shape="rect" class="external-link" href="http://
 tapestry.apache.org/current/apidocs/org/apache/tapestry5/ValueEncoder.html">ValueEncoder</a> is used to convert between client-side strings and server-side objects. The <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ValueEncoderSource.html">ValueEncoderSource</a> service provides the necessary value encoders.</p><p>As shown in the example above, most of the parameters passed to the event handler method are derived from the values provided in the event context. Each successive method parameter matches against a value provided in the event context (the context parameter of the ActionLink component; though many components have a similar context parameter).</p><p>In some cases, it is desirable to have direct access to the context (for example, to adapt to cases where there are a variable number of context values). The context values may be passed to an event handler method as parameter of the following types:</p><ul><
 li><a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/EventContext.html">EventContext</a></li><li>Object[]</li><li>List&lt;Object&gt;</li></ul><p>The latter two should be avoided, they may be removed in a future release. In all of these cases, the context parameter acts as a freebie; it doesn't match against a context value as it represents <em>all</em> context values.</p><h2 id="ComponentEvents-AccessingRequestQueryParameters">Accessing Request Query Parameters</h2><p>A parameter may be annotated with the @RequestParameter annotation; this allows a query parameter to be extracted from the request, converted to the correct type, and passed to the method. Again, this doesn't count against the event context values.</p><h2 id="ComponentEvents-MethodMatching">Method Matching</h2><p>An event handler method will only be invoked <em>if the context contains at least as many values as the method has parameters</em>. Methods with too ma
 ny parameters will be silently skipped.</p><p>Tapestry will silently skip over a method if there are insufficient values in the context to satisfy the number of parameters requested.</p><p>EventContext parameters, and parameters annotated with @RequestParameter, do not count against this limit.</p><h2 id="ComponentEvents-MethodOrdering">Method Ordering</h2><p>When multiple methods match within the same class, Tapestry will invoke them in ascending alphabetical order. When there are multiple overrides of the same method name, Tapestry invokes them in descending order by number of parameters. In general, these situations don't happen ... in most cases, only a single method is required to handle a specific event form a specific component.</p><p>An event handler method may return the value <code>true</code> to indicate that the event has been handled; this immediately stops the search for additional methods in the same class (or in base classes) or in containing components.</p><h1 id="C
 omponentEvents-EventBubbling">Event Bubbling</h1><p>The event will bubble up the hierarchy, until it is aborted. The event is aborted when an event handler method returns a non-null value.</p><p>Returning a boolean value from an event handler method is special. Returning true will abort the event with no result; use this when the event is fully handled without a return value and no further event handlers (in the same component, or in containing components) should be invoked.</p><p>Returning false is the same as returning null; event processing will continue to look for more event handlers, in the same component or its parent.</p><p>When an event bubbles up from a component to its container, the origin of the event is changed to be the component. For example, a Form component inside a BeanEditForm component may fire a success event. The page containing the BeanEditForm may listen for that event, but it will be from the BeanEditForm component (which makes sense, because the id of the 
 Form inside the BeanEditForm is part of the BeanEditForm's implementation, not its public interface).</p><h1 id="ComponentEvents-EventMethodExceptions">Event Method Exceptions</h1><p>Event methods are allowed to throw any exception (not just runtime exceptions). If an event method does throw an exception, Tapestry will catch the thrown exception and ultimately display the exception report page.</p><p>In other words, there's no need to do this:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  void onActionFromRunQuery()
   {
     try
     {
@@ -191,7 +106,7 @@
   }
 ]]></script>
 </div></div><p>Instead, you may simply say:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  void onActionFromRunQuery() throws JDBCException
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  void onActionFromRunQuery() throws JDBCException
   {
     dao.executeQuery();
   }
@@ -199,7 +114,7 @@
 </div></div><p>Your event handler method may even declare that it "throws Exception" if that is more convenient.</p><h1 id="ComponentEvents-InterceptingEventExceptions">Intercepting Event Exceptions</h1><p>When an event handler method throws an exception (checked or runtime), Tapestry gives the component and its containing page a chance to handle the exception, before continuing on to report the exception.</p><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:0 1em">
 <p>    <strong>JumpStart Demo:</strong><br clear="none">
     <a shape="rect" class="external-link" href="http://jumpstart.doublenegative.com.au/jumpstart/examples/infrastructure/handlingabadcontext/1" >Handling A Bad Context</a></p></div><p>Tapestry emits a new event, of type "exception", passing the thrown exception as the context. In fact, the exception is wrapped inside a <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/runtime/ComponentEventException.html">ComponentEventException</a>, from which you may extract the event type and context.</p><p>Thus:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  Object onException(Throwable cause)
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  Object onException(Throwable cause)
   {
     message = cause.getMessage();
 

Modified: websites/production/tapestry/content/component-libraries.html
==============================================================================
--- websites/production/tapestry/content/component-libraries.html (original)
+++ websites/production/tapestry/content/component-libraries.html Sat Jun 27 21:21:02 2015
@@ -27,16 +27,6 @@
   </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 type="text/javascript">
-  SyntaxHighlighter.defaults['toolbar'] = false;
-  SyntaxHighlighter.all();
-  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -55,7 +45,7 @@
   <input type="submit" value="Search">
 </form>
 
-</div><div class="emblem" style="float:left"><p><a shape="rect" href="index.html"><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"></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Component Libraries</h1></div></div>
+</div><div class="emblem" style="float:left"><p><a shape="rect" 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">Component Libraries</h1></div></div>
 <div class="clearer"></div>
 </div>
 
@@ -75,14 +65,8 @@ table.ScrollbarTable td.ScrollbarParent
 table.ScrollbarTable td.ScrollbarNextName {text-align: right;border: none;}
 table.ScrollbarTable td.ScrollbarNextIcon {text-align: center;width: 16px;border: none;}
 
-/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="supporting-informal-parameters.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="supporting-informal-parameters.html">Supporting Informal Parameters</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="cookbook.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="cookbook.html">Cookbook</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="switching-cases.html">Switching Cases</a></td><td colspan="1" rowspan="1" class="ScrollbarNextIcon"><a shape="rect" href="switching
 -cases.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div>    <div class="aui-message problem shadowed information-macro">
-                            <span class="aui-icon icon-problem">Icon</span>
-                <div class="message-content">
-                            <p>This page has not yet been fully updated for Tapestry 5.4. Things are different and simpler in 5.4 than in previous releases.</p>
-                    </div>
-    </div>
-<h1 id="ComponentLibraries-CreatingComponentLibraries">Creating Component Libraries</h1><p>Nearly every Tapestry application includes a least a couple of custom components, specific to the application. What's exciting about Tapestry is how easy it is to package components for reuse across many applications ... and the fact that applications using a component library need no special configuration.</p><p>A Tapestry component library consists of components (and optionally mixins, pages and component base classes). In addition, a component library will have a module that can define new services (needed by the components) or configure other services present in Tapestry. Finally, components can be packaged with <em>assets</em>: resources such as images, stylesheets and JavaScript libraries that need to be provided to the client web browser.</p><p>We're going to create a somewhat insipid component that displays a large happy face icon.</p><p>Tapestry doesn't mandate that you use any build 
 system, but we'll assume for the moment that you are using Maven 2. In that case, you'll have a pom.xml file something like the following:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>pom.xml</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[&lt;project&gt;
+/*]]>*/</style><div class="Scrollbar"><table class="ScrollbarTable"><tr><td colspan="1" rowspan="1" class="ScrollbarPrevIcon"><a shape="rect" href="supporting-informal-parameters.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/back_16.gif" width="16" height="16"></a></td><td colspan="1" rowspan="1" class="ScrollbarPrevName" width="33%"><a shape="rect" href="supporting-informal-parameters.html">Supporting Informal Parameters</a>&#160;</td><td colspan="1" rowspan="1" class="ScrollbarParent" width="33%"><sup><a shape="rect" href="cookbook.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/up_16.gif" width="8" height="8"></a></sup><a shape="rect" href="cookbook.html">Cookbook</a></td><td colspan="1" rowspan="1" class="ScrollbarNextName" width="33%">&#160;<a shape="rect" href="switching-cases.html">Switching Cases</a></td><td colspan="1" rowspan="1" class="ScrollbarNextIcon"><a shape="rect" href="switching
 -cases.html"><img align="middle" border="0" src="https://cwiki.apache.org/confluence/images/icons/forwd_16.gif" width="16" height="16"></a></td></tr></table></div><div class="confluence-information-macro confluence-information-macro-warning"><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>This page has not yet been fully updated for Tapestry 5.4. Things are different and simpler in 5.4 than in previous releases.</p></div></div><h1 id="ComponentLibraries-CreatingComponentLibraries">Creating Component Libraries</h1><p>Nearly every Tapestry application includes a least a couple of custom components, specific to the application. What's exciting about Tapestry is how easy it is to package components for reuse across many applications ... and the fact that applications using a component library need no special configuration.</p><p>A Tapestry component library consists of components (and opt
 ionally mixins, pages and component base classes). In addition, a component library will have a module that can define new services (needed by the components) or configure other services present in Tapestry. Finally, components can be packaged with <em>assets</em>: resources such as images, stylesheets and JavaScript libraries that need to be provided to the client web browser.</p><p>We're going to create a somewhat insipid component that displays a large happy face icon.</p><p>Tapestry doesn't mandate that you use any build system, but we'll assume for the moment that you are using Maven 2. In that case, you'll have a pom.xml file something like the following:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>pom.xml</b></div><div class="codeContent panelContent pdl">
+<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[&lt;project&gt;
   &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
   &lt;groupId&gt;org.example&lt;/groupId&gt;
   &lt;artifactId&gt;happylib&lt;/artifactId&gt;
@@ -151,7 +135,7 @@ table.ScrollbarTable td.ScrollbarNextIco
 &lt;/project&gt;
 ]]></script>
 </div></div><p>You will need to modify the Tapestry release version number ("5.2.0" in the listing above) to reflect the current version of Tapestry when you create your component library.</p><p>We'll go into more detail about the relevant portions of this POM in the later sections.</p><h2 id="ComponentLibraries-Step1:Chooseabasepackagename">Step 1: Choose a base package name</h2><p>Just as with Tapestry applications, Tapestry component libraries should have a <em>unique</em> base package name. In this example, we'll use <code>org.examples.happylib</code>.</p><p>As with an application, we'll follow the conventions: we'll place the module for this library inside the services package, and place pages and components under their respective packages.</p><h2 id="ComponentLibraries-Step2:Createyourpagesand/orcomponents">Step 2: Create your pages and/or components</h2><p>Our component is very simple:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeade
 r pdl" style="border-bottom-width: 1px;"><b>HappyIcon.java</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[package org.example.happylib.components;
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[package org.example.happylib.components;
 
 import org.apache.tapestry5.Asset;
 import org.apache.tapestry5.MarkupWriter;
@@ -174,7 +158,7 @@ public class HappyIcon
 }
 ]]></script>
 </div></div><p>HappyIcon appears inside the components sub-package. The happyIcon field is injected with the the Asset for the file <code>happy.jpg</code>. The path specified with the @Path annotation is relative to the <code>HappyIcon.class</code> file; it should be stored in the project under <code>src/main/resources/org/example/happylib/components</code>.</p><p>Tapestry ensures that the <code>happy.jpg</code> asset can be accessed from the client web browser; the src attribute of the &lt;img&gt; tag will be a URL that directly accesses the image file ... there's no need to unpackage the <code>happy.jpg</code> file. This works for any asset file stored under the library's root package.</p><p>This component renders out an <code>&lt;img&gt;</code> tag for the icon.</p><p>Often, a component library will have many different components, or even pages.</p><h2 id="ComponentLibraries-Step3:Chooseavirtualfoldername">Step 3: Choose a virtual folder name</h2><p>In Tapestry, components that h
 ave been packaged in a library are referenced using a virtual folder name. It's effectively as if the application had a new root-level folder containing the components.</p><p>In our example, we'll use "happy" as the folder name. That means the application can include the HappyIcon component in the template using any of the following, which are all equivalent:</p><ul><li>&lt;t:happy.happyicon/&gt;</li><li>&lt;t:happy.icon/&gt;</li><li>&lt;img t:type="happy.happyicon"/&gt;</li><li>&lt;img t:type="happy/icon"/&gt;</li></ul><p>Why "icon" vs. "happyicon"? Tapestry notices that the folder name, "happy" is a prefix or suffix of the class name ("HappyIcon") and creates an alias that strips off the prefix (or suffix). To Tapestry, they are completely identical: two different aliases for the same component class name.</p><p>The above naming is somewhat clumsy, and can be improved by introducing an additional namespace into the template:</p><div class="code panel pdl" style="border-width: 1px;
 "><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[&lt;html xmlns:t=&quot;http://tapestry.apache.org/schema/tapestry_5_1_0.xsd&quot;
+<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[&lt;html xmlns:t=&quot;http://tapestry.apache.org/schema/tapestry_5_1_0.xsd&quot;
   xmlns:h=&quot;tapestry-library:happy&quot;&gt;
 
   ...
@@ -185,7 +169,7 @@ public class HappyIcon
 &lt;/html&gt;
 ]]></script>
 </div></div><p>The special namespace mapping for sets up namespace prefix "h:" to mean the same as "happy/". It then becomes possible to reference components within the happy virtual folder directly.</p><h2 id="ComponentLibraries-Step4:Configurethevirtualfolder">Step 4: Configure the virtual folder</h2><p>Tapestry needs to know where to search for your component class. This is accomplished in your library's IoC module class, by making a <em>contribution</em> to the ComponentClassResolver service configuration.</p><p>At application startup, Tapestry will read the library module along with all other modules and configure the ComponentClassResolver service using information in the module:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>HappyModule.java</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[package org.example.happylib.services;
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[package org.example.happylib.services;
 
 import org.apache.tapestry5.ioc.Configuration;
 import org.apache.tapestry5.services.LibraryMapping;
@@ -198,14 +182,8 @@ public class HappyModule
     }
 }
 ]]></script>
-</div></div><p>The ComponentClassResolver service is responsible for mapping libraries to packages; it takes as a contribution a collection of these LibraryMapping objects. Every module may make its own contribution to the ComponentClassResolver service, mapping its own package ("org.example.happylib") to its own folder ("happy").</p><p>This module class is also where you would define new services that can be accessed by your components (or other parts of the application).</p>    <div class="aui-message warning shadowed information-macro">
-                            <span class="aui-icon icon-warning">Icon</span>
-                <div class="message-content">
-                            <p>It is possible to add a mapping for "core", the core library for Tapestry components; all the built-in Tapestry components (TextField, BeanEditForm, Grid, etc.) are actually in the core library. When Tapestry doesn't find a component in your application, it next searches inside the "core" library. Contributing an additional package as "core" simply extends the number of packages searched for core components (it doesn't replace Tapestry's default package, org.apache.tapestry5.corelib). Adding to "core" is sometimes reasonable, if you ensure that there is virtually no chance of a naming conflict (via different modules contributing packages to core with conflicting class names).</p>
-                    </div>
-    </div>
-<h2 id="ComponentLibraries-Step5:Configurethemoduletoautoload">Step 5: Configure the module to autoload</h2><p>For Tapestry to load your module at application startup, it is necessary to put an entry in the JAR manifest. This is taken care of in the pom.xml above:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>pom.xml (partial)</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[      &lt;plugin&gt;
+</div></div><p>The ComponentClassResolver service is responsible for mapping libraries to packages; it takes as a contribution a collection of these LibraryMapping objects. Every module may make its own contribution to the ComponentClassResolver service, mapping its own package ("org.example.happylib") to its own folder ("happy").</p><p>This module class is also where you would define new services that can be accessed by your components (or other parts of the application).</p><div class="confluence-information-macro confluence-information-macro-note"><span class="aui-icon aui-icon-small aui-iconfont-warning confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>It is possible to add a mapping for "core", the core library for Tapestry components; all the built-in Tapestry components (TextField, BeanEditForm, Grid, etc.) are actually in the core library. When Tapestry doesn't find a component in your application, it next searches inside the "core" 
 library. Contributing an additional package as "core" simply extends the number of packages searched for core components (it doesn't replace Tapestry's default package, org.apache.tapestry5.corelib). Adding to "core" is sometimes reasonable, if you ensure that there is virtually no chance of a naming conflict (via different modules contributing packages to core with conflicting class names).</p></div></div><h2 id="ComponentLibraries-Step5:Configurethemoduletoautoload">Step 5: Configure the module to autoload</h2><p>For Tapestry to load your module at application startup, it is necessary to put an entry in the JAR manifest. This is taken care of in the pom.xml above:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>pom.xml (partial)</b></div><div class="codeContent panelContent pdl">
+<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[      &lt;plugin&gt;
            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
            &lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
            &lt;configuration&gt;
@@ -218,28 +196,21 @@ public class HappyModule
        &lt;/plugin&gt;
 ]]></script>
 </div></div><h2 id="ComponentLibraries-Step6:ExtendingClientAccess">Step 6: Extending Client Access</h2><p>As of Tapestry 5.2, a new step is needed: extending access for the assets. This is accomplished in your library's module class, HappyModule:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[public static void contributeRegexAuthorizer(Configuration&lt;String&gt; configuration)
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[public static void contributeRegexAuthorizer(Configuration&lt;String&gt; configuration)
 {
     configuration.add(&quot;^org/example/happylib/.*\\.jpg$&quot;);
 }
 ]]></script>
 </div></div><p>This contribution uses a regular expression to identify that any resource on the classpath under the org/example/happylib folder with a jpg extension is allowed. If you had a mix of different image types, you could replace jpg with (jpg|gif|png).</p><h2 id="ComponentLibraries-Step7:VersioningAssets">Step 7: Versioning Assets</h2><p>Classpath assets, those packaged in JAR files (such as the happy.jpg asset) are retrieved by the client web browser using a URL that reflects the package name. Tapestry users a special virtual folder, /assets, under the context folder for this purpose.</p><p>The image file here is exposed to the web browser via the URL /happyapp/assets/org/example/happylib/components/happy.jpg (this assumes that the application was deployed as happyapp.war).</p><p>Tapestry uses a far-future expiration date for classpath assets; this allows browsers to aggressively cache the file, but in Tapestry 5.1 and earlier this causes a problem when a later version of 
 the library changes the file. This is discussed in detail in <a shape="rect" class="external-link" href="http://developer.yahoo.com/performance/rules.html#expires" >Yahoo's Performance Best Practices</a>.</p><p>To handle this problem in Tapestry 5.1 and earlier, you should map your library assets to a versioned folder. This can be accomplished using another contribution from the HappyModule, this time to the ClasspathAssetAliasManager service whose configuration maps a virtual folder underneath /assets to a package:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[public static void contributeClasspathAssetAliasManager(MappedConfiguration&lt;String, String&gt; configuration)
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[public static void contributeClasspathAssetAliasManager(MappedConfiguration&lt;String, String&gt; configuration)
 {
     configuration.add(&quot;happylib/1.0&quot;, &quot;org/example/happylib&quot;);
 }
 ]]></script>
 </div></div><p>With this in place, and the library and applications rebuilt and redeployed, the URL for happy.jpg becomes /happyapp/assets/happylib/1.0/components/happy.jpg. This is shorter, but also incorporates a version number ("1.0") that can be changed in a later release.</p>
 
-    <div class="aui-message hint shadowed information-macro">
-                    <p class="title">Added in 5.2</p>
-                            <span class="aui-icon icon-hint">Icon</span>
-                <div class="message-content">
-                            
-
-                    </div>
-    </div>
-
+<div class="confluence-information-macro confluence-information-macro-information"><p class="title">Added in 5.2</p><span class="aui-icon aui-icon-small aui-iconfont-info confluence-information-macro-icon"></span><div class="confluence-information-macro-body">
+</div></div>
 <div style="border-right: 20px solid #D8E4F1;border-left: 20px solid #D8E4F1;">
 <p>In version 5.2 and later, Tapestry automatically creates a mapping for assets inside your JAR. In the above example, the icon image will be exposed as <code>/assets/</code><em>application version</em><code>/happy/components/happy.jpg</code> (the application version number is incorporated into the URL). The "happy" portion is a virtual folder that maps to the library's root package (as folder <code>org/example/happylib</code> on the Java classpath). The application version is a configurable value.</p>
 </div><h2 id="ComponentLibraries-Conclusion">Conclusion</h2><p>That's it! Autoloading plus the virtual folders for components and for assets takes care of all the issues related to components. Just build your JARs, setup the JAR Manifest, and drop them into your applications.</p></div>

Modified: websites/production/tapestry/content/component-mixins.html
==============================================================================
--- websites/production/tapestry/content/component-mixins.html (original)
+++ websites/production/tapestry/content/component-mixins.html Sat Jun 27 21:21:02 2015
@@ -27,16 +27,6 @@
   </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 type="text/javascript">
-  SyntaxHighlighter.defaults['toolbar'] = false;
-  SyntaxHighlighter.all();
-  </script>
 
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -55,7 +45,7 @@
   <input type="submit" value="Search">
 </form>
 
-</div><div class="emblem" style="float:left"><p><a shape="rect" href="index.html"><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"></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Component Mixins</h1></div></div>
+</div><div class="emblem" style="float:left"><p><a shape="rect" 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">Component Mixins</h1></div></div>
 <div class="clearer"></div>
 </div>
 
@@ -68,71 +58,24 @@
 
 <div id="content">
 <div id="ConfluenceContent"><p>A <strong>Component Mixin</strong> is a way to supplement an existing Tapestry component with additional behavior.</p><div class="navmenu" style="float:right; background:#eee; margin:3px; padding:3px">
-<h3>Related Articles</h3>
-<ul class="content-by-label"><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="component-cheat-sheet.html">Component Cheat Sheet</a>
-                    
-                
-                            </div>
-        </li><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="page-and-component-classes-faq.html">Page And Component Classes FAQ</a>
-                    
-                
-                            </div>
-        </li><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="component-templates.html">Component Templates</a>
-                    
-                
-                            </div>
-        </li><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="component-parameters.html">Component Parameters</a>
-                    
-                
-                            </div>
-        </li><li>
-            <div>
-                    <span class="icon icon-page" title="Page">Page:</span>            </div>
-
-            <div class="details">
-                            <a shape="rect" href="legacy-javascript.html">Legacy JavaScript</a>
-                    
-                
-                            </div>
-        </li></ul>
-</div><p>You can think of a mixin as a kind of mashup for a component; it combines the new behavior of the mixin with the existing behavior of the component, and bundles it all in one place. Mixins may be used to add specialized validation to user input fields, dynamically modify the HTML output of a component, or to add Ajax effects and behaviors of all sorts to components.</p><p>Tapestry comes with several mixins, such as the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/mixins/Autocomplete.html">Autocomplete mixin</a> which adds autocomplete behavior to an ordinary TextField Component. In addition, you can easily create your own.</p><h2 id="ComponentMixins-MixinClasses">Mixin Classes</h2><p>Mixin classes are stored in the <code>mixins</code> sub-package of your application, below the application (or library) root package. This parallels where your component and page classes are stored.</p><p>Other than that, mi
 xin classes are the same as any other component class.</p><h2 id="ComponentMixins-MixinLimitations">Mixin Limitations</h2><p>Currently, mixins are allowed to do anything a component can do, including having parameters and render phase methods.</p><p>Mixins may not have a template. They integrate with the component strictly in terms of invoking render phase methods.</p><p>Mixins may have persistent fields, but currently, this is not implemented perfectly (there is a potential for a name clash between a mixin and the component or another mixin). Use persistent fields with mixins with care ... or better yet, delegate persistence to the container using parameters.</p><p>Mixins may not, themselves, have mixins.</p><h2 id="ComponentMixins-UsingMixins">Using Mixins</h2><p>Mixins are used in two different scenarios: <em>Instance mixins</em> and <em>Implementation mixins</em>.</p><h3 id="ComponentMixins-InstanceMixins">Instance Mixins</h3><p>An instance mixin is a mixin applied to a specific
  <em>instance</em> of a component. This can be done in the <a shape="rect" href="component-templates.html">component template</a> with the <code>mixins</code> attribute of the component tag. This is a comma-separated list of mixin names.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[&lt;t:textfield t:id=&quot;accountName&quot; t:mixins=&quot;Autocomplete,DefaultFromCookie&quot; /&gt;
+<div class="error"><span class="error">Error formatting macro: contentbylabel: com.atlassian.confluence.api.service.exceptions.BadRequestException: Could not parse cql : null</span> </div></div><p>You can think of a mixin as a kind of mashup for a component; it combines the new behavior of the mixin with the existing behavior of the component, and bundles it all in one place. Mixins may be used to add specialized validation to user input fields, dynamically modify the HTML output of a component, or to add Ajax effects and behaviors of all sorts to components.</p><p>Tapestry comes with several mixins, such as the <a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/mixins/Autocomplete.html">Autocomplete mixin</a> which adds autocomplete behavior to an ordinary TextField Component. In addition, you can easily create your own.</p><h2 id="ComponentMixins-MixinClasses">Mixin Classes</h2><p>Mixin classes are stored in the <cod
 e>mixins</code> sub-package of your application, below the application (or library) root package. This parallels where your component and page classes are stored.</p><p>Other than that, mixin classes are the same as any other component class.</p><h2 id="ComponentMixins-MixinLimitations">Mixin Limitations</h2><p>Currently, mixins are allowed to do anything a component can do, including having parameters and render phase methods.</p><p>Mixins may not have a template. They integrate with the component strictly in terms of invoking render phase methods.</p><p>Mixins may have persistent fields, but currently, this is not implemented perfectly (there is a potential for a name clash between a mixin and the component or another mixin). Use persistent fields with mixins with care ... or better yet, delegate persistence to the container using parameters.</p><p>Mixins may not, themselves, have mixins.</p><h2 id="ComponentMixins-UsingMixins">Using Mixins</h2><p>Mixins are used in two different 
 scenarios: <em>Instance mixins</em> and <em>Implementation mixins</em>.</p><h3 id="ComponentMixins-InstanceMixins">Instance Mixins</h3><p>An instance mixin is a mixin applied to a specific <em>instance</em> of a component. This can be done in the <a shape="rect" href="component-templates.html">component template</a> with the <code>mixins</code> attribute of the component tag. This is a comma-separated list of mixin names.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[&lt;t:textfield t:id=&quot;accountName&quot; t:mixins=&quot;Autocomplete,DefaultFromCookie&quot; /&gt;
 ]]></script>
 </div></div><p>Alternately, when the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Component.html">Component</a> annotation is used to define the component type, you may specify the mixins in two ways:</p><ul><li>The @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Mixins.html">Mixins</a> annotation allows a list of mixin names to be specified.</li><li>The @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/MixinClasses.html">MixinClasses</a> annotation allows a set of mixin classes to be specified directly.</li></ul><p>The former is often less verbose, and allows core mixins to be overridden with application-specific mixins. The later format is more specific and more refactor-safe (renaming a mixin class will rename the entry in the MixinClasses annotation as well).</p>
 <p>Example:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @Component(parameters=. . .) @Mixins({&quot;Autocomplete&quot;, &quot;DefaultFromCookie&quot;})
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @Component(parameters=. . .) @Mixins({&quot;Autocomplete&quot;, &quot;DefaultFromCookie&quot;})
   private TextField userId;
 ]]></script>
 </div></div><p>This example defines a component of type TextField and mixes in the <em>hypothetical</em> Autocomplete and DefaultFromCookie mixins.</p><h3 id="ComponentMixins-OrderingtheMixins">Ordering the Mixins</h3><p>With @Mixins and @MixinClasses annotations, we can order the list of mixins, by adding a constraint.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @Component(parameters=. . .) @Mixins({&quot;Autocomplete&quot;, &quot;DefaultFromCookie::before:Autocomplete&quot;})
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @Component(parameters=. . .) @Mixins({&quot;Autocomplete&quot;, &quot;DefaultFromCookie::before:Autocomplete&quot;})
   private TextField userId;
 ]]></script>
 </div></div><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @Component(parameters=. . .) 
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @Component(parameters=. . .) 
   @MixinClasses(value={Autocomplete.class, DefaultFromCookie.class}, order={&quot;&quot;,&quot;before:AutoComplete&quot;})
   private TextField userId;
 ]]></script>
 </div></div><p>You can specify many contraints for a mixin. You just need to separate them with a ";".</p><h3 id="ComponentMixins-ImplementationMixins">Implementation Mixins</h3><p>Implementation mixins, mixins which apply to all instances of a component, are added using the @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Mixin.html">Mixin</a> annotation. This annotation defines a field that will contain the mixin instance.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[public class AutocompleteField extends TextField
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[public class AutocompleteField extends TextField
 {
   @Mixin
   private Autocomplete autocompleteMixin;
@@ -141,7 +84,7 @@
 }
 ]]></script>
 </div></div><p>Often, the type of the field is the exact mixin class to be instantiated.</p><p>In other cases, such as when the field's type is an interface or a base class, the value attribute of the annotation will be used to determine the mixin class name:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[public class AutocompleteField extends TextField
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[public class AutocompleteField extends TextField
 {
   @Mixin(&quot;Autocomplete&quot;)
   private Object autocompleteMixin;
@@ -150,11 +93,11 @@
 }
 ]]></script>
 </div></div><h2 id="ComponentMixins-MixinParameters">Mixin Parameters</h2><p>Mixins are allowed to have parameters, just like components.</p><p>When binding parameters (either in the template, or using the parameters attribute of the Component annotation), Tapestry will match each parameter name against the parameters defined by each class (which is to say, the component and each mixin).</p><p>If the component and a mixin both define a parameter with the same name, then the component wins: the component's parameter will be bound, and the mixin's parameter will be unbound.</p><p>Alternately, you may prefix the name of the parameter with the <em>unqualified</em> name of the Mixin class; this eliminates the ambiguity. Example:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @Component(parameters={&quot;Autocomplete.id=auto&quot;, . . . }) @Mixins(&quot;Autocomplete&quot;, &quot;DefaultFromCookie&quot;})
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @Component(parameters={&quot;Autocomplete.id=auto&quot;, . . . }) @Mixins(&quot;Autocomplete&quot;, &quot;DefaultFromCookie&quot;})
   private TextField userId;
 ]]></script>
 </div></div><p>If the component and a mixin both supports informal parameters, the mixin will receive the all the unqualified informal parameters. If more than one Mixin supports informal parameters the results are undefined.</p><p>Note that when you define an implementation mixin, and the mixin has parameters, there's no way to bind those parameters as part of the <em>implementation</em>. They simply become available when the composite component (including the mixin) is introduced into a page.</p><h2 id="ComponentMixins-Bindingtheparameterofthecorecomponent">Binding the parameter of the core component</h2><p>It is sometimes desirable to access the current value of a parameter defined in the component associated with the mixin. For example: normally, when the textfield component is marked disabled, it renders a text field with a disabled attribute, but you want it to output the (plaintext) value when disabled. A mixin for this purpose would need access to at least the disabled, and 
 value parameters, and possibly the translate parameter (for a client-side representation). You can access the disabled parameter via @InjectContainer and checking isDisabled on the field, but textfield currently provides no access to value or translate. In this case, you can bind the core-component parameter using the @BindParameter annotation:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  public class MyMixin
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  public class MyMixin
   {
     @BindParameter
     private boolean disabled;
@@ -179,11 +122,11 @@
     ....
 ]]></script>
 </div></div><p>Tapestry will "link" the disabled, translate, and value fields above to parameters of the same name on the associated component. The fields are not parameters to the mixin, but local copies of the component parameter. They are cached only if the associated component parameter is cached. They are read-write, and Tapestry handles synchronizing the value between mixins and the associated component such that even with a cached parameter, components and mixins will share the same value for a given parameter/bound-parameter during render. Only declared parameters of the associated components may be bound.</p><p>By default, Tapestry will bind the parameter with the same name as the field. You can explicitly declare the parameter to bind via the value attribute:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @BindParameter(&quot;translate&quot;)
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @BindParameter(&quot;translate&quot;)
   private FieldTranslator translator;
 ]]></script>
 </div></div><p>In same cases, a mixin will be used on different components using different names for a similar parameter type. For instance, BeanEditor has an "object" parameter; most form fields have a "value" parameter, and Grid has a "source" parameter. These parameters have different names but share the feature of being the "principle" parameter on which the components are acting. A mixin useable by all three components can specify multiple potential parameter values to bind. The first value that matches a declared parameter of the associated component will be used:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[public class MyMixin
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[public class MyMixin
 {
   ...
   @BindParameter({&quot;value&quot;,&quot;object&quot;,&quot;source&quot;})
@@ -192,20 +135,20 @@
 }
 ]]></script>
 </div></div><p>"MyMixin" can be used on a textfield (principalObject is bound to "value"), on BeanEditor or BeanDisplay (principalObject is bound to "object"), or on Grid or Loop (principalObject is bound to "source").</p><h2 id="ComponentMixins-RenderPhaseOrdering">Render Phase Ordering</h2><p>All mixins for a component execute their render phase methods <em>before</em> the component's render phase methods for most phases. However, in the later phases (AfterRender, CleanupRender) the order of executing is reversed.</p><p>Exception: A mixins whose class is annotated with @<a shape="rect" class="external-link" href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/MixinAfter.html">MixinAfter</a> is ordered <em>after</em> the component, not before.</p><p>Withing a given phase and class (@MixinAfter vs. mixin before), mixin ordering is determined by the ordering constraints specified in the mixin definitions. The constraint definitions follow the same convent
 ions as <a shape="rect" href="ordering-by-constraints.html">ordered service configurations</a>. How you specify the constraints depends on how the mixin is specified.</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>As an Implementation Mixin</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @Mixin(&quot;Autocomplete&quot;,order={&quot;before:DiscardBody&quot;,&quot;after:RenderDisabled&quot;}
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @Mixin(&quot;Autocomplete&quot;,order={&quot;before:DiscardBody&quot;,&quot;after:RenderDisabled&quot;}
   private TextField userId;
 ]]></script>
 </div></div><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>As a Template-specifed Instance Mixin</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: xml; gutter: false" type="syntaxhighlighter"><![CDATA[  &lt;input t:id=&quot;myfield&quot; t:mixins=&quot;autocomplete::before:discardbody;after:renderdisabled,
+<script class="brush: xml; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  &lt;input t:id=&quot;myfield&quot; t:mixins=&quot;autocomplete::before:discardbody;after:renderdisabled,
           defaultfromcookie::before:autocomplete&quot;/&gt;
 ]]></script>
 </div></div><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>As a @Mixins-specified Instance Mixin</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @Component(...)
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @Component(...)
   @Mixins(&quot;Autocomplete::before:discardbody;after:renderdisabled&quot;,&quot;DefaultFromCookie::before:autocomplete&quot;))
   private TextField userId;
 ]]></script>
 </div></div><div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>As a @MixinClasses-specified Instance Mixins</b></div><div class="codeContent panelContent pdl">
-<script class="theme: Default; brush: java; gutter: false" type="syntaxhighlighter"><![CDATA[  @Component(...)
+<script class="brush: java; gutter: false; theme: Default" type="syntaxhighlighter"><![CDATA[  @Component(...)
   @MixinClasses(value={Autocomplete.class,DefaultFromCookie.class},
                 order={&quot;before:discardbody;after:renderdisabled&quot;,&quot;before:autocomplete&quot;)
 ]]></script>



Mime
View raw message