Modified: websites/production/tapestry/content/developer-bible.html
==============================================================================
--- websites/production/tapestry/content/developer-bible.html (original)
+++ websites/production/tapestry/content/developer-bible.html Wed Sep 20 
12:29:16 2017
@@ -27,6 +27,14 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
+    <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
+        <script>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -36,26 +44,13 @@
 
   <div class="wrapper bs">
 
-        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div>
-
-</div>
+        <div id="navigation"><div class="nav"><ul class="alternate"><li><a  
href="index.html">Home</a></li><li><a  href="getting-started.html">Getting 
Started</a></li><li><a  href="documentation.html">Documentation</a></li><li><a  
href="download.html">Download</a></li><li><a  
href="about.html">About</a></li><li><a  class="external-link" 
href="http://www.apache.org/licenses/LICENSE-2.0";>License</a></li><li><a  
href="community.html">Community</a></li><li><a  class="external-link" 
href="http://www.apache.org/security/";>Security</a></li><li><a  
class="external-link" href="http://www.apache.org/";>Apache</a></li><li><a  
class="external-link" 
href="http://www.apache.org/foundation/sponsorship.html";>Sponsorship</a></li><li><a
  class="external-link" 
href="http://www.apache.org/foundation/thanks.html";>Thanks</a></li></ul></div></div>
 
           <div id="top">
-            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span>
-<form enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";>
-  <input type="text" name="q">
-  <input type="submit" value="Search">
-</form>
-
-</div>
-
-
-<div class="emblem" style="float:left"><p><a  href="index.html"><span 
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image 
confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div>
-
-
-<div class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Developer Bible</h1></div>
-
-</div>
+            <div id="smallbanner"><div class="searchbox" 
style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; 
font-size: 90%">Tapestry docs, issues, wikis &amp; blogs:</span><form 
enctype="application/x-www-form-urlencoded" method="get" 
action="http://tapestry.apache.org/search.html";> 
+ <input type="text" name="q"> 
+ <input type="submit" value="Search"> 
+</form></div><div class="emblem" style="float:left"><p><a  
href="index.html"><span class="confluence-embedded-file-wrapper"><img 
class="confluence-embedded-image confluence-external-resource" 
src="http://tapestry.apache.org/images/tapestry_small.png"; 
data-image-src="http://tapestry.apache.org/images/tapestry_small.png";></span></a></p></div><div
 class="title" style="float:left; margin: 0 0 0 3em"><h1 
id="SmallBanner-PageTitle">Developer Bible</h1></div></div>
       <div class="clearer"></div>
       </div>
 
@@ -67,7 +62,44 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p>IDE choices, coding style and 
formatting, commit practices, naming conventions and other issues relevant to 
Tapestry committers &amp; contributers.</p><parameter 
ac:name="style">float:right</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter 
ac:name="class">aui-label</parameter><rich-text-body><parameter 
ac:name="showLabels">false</parameter><parameter 
ac:name="showSpace">false</parameter><parameter ac:name="title">Related 
Articles</parameter><parameter ac:name="cql">label = "tapestry-dev" and space = 
currentSpace()</parameter></rich-text-body><h2 
id="DeveloperBible-IDEChoices">IDE Choices</h2><h3 
id="DeveloperBible-IntelliJ">IntelliJ</h3><p>It's a free license for all 
committers and it's just better. Yes, the first few days can be an unpleasant 
fumble because everything is almost, but not quite, familiar. Pretty soon 
you'll love IDEA and recognize that Eclipse has been bending you over and doing 
unspeakable thi
 ngs.</p><p>There are shared code formatting settings in the <a  
class="external-link" 
href="https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree;f=support";>support
 directory</a> (idea-settings.jar). This will prevent unexpected conflicts due 
to formatting.</p><h3 id="DeveloperBible-Eclipse">Eclipse</h3><p>Howard uses 
this ... because he can't manage to switch IDEs constantly (he uses Eclipse for 
training). Lately its gotten better.</p><p>As with IntelliJ, there are shared 
code formatting settings for Eclipse in the <a  class="external-link" 
href="https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree;f=support";>support
 directory</a> (tapestry-indent-eclipse.xml).</p><h2 
id="DeveloperBible-Copyrights">Copyrights</h2><p>All source files should have 
the ASF copyright comment on top, except where such a comment would interfere 
with its behavior. For example, component template files omit the 
comment.</p><p>As you make changes to files, update the copyright to add the
  current year to the list. The goal is that the copyright notice includes the 
year in which files change. When creating a new file, don't back date the 
copyright year ... start with the current year. Try not to change the copyright 
year on files that haven't actually changed.</p><p>IntelliJ has a great 
comparison view: Cmd-9 to see the local changes, the Cmd-D to see the 
differences. You can whip through the changes (using Cmd-forward arrow) and 
make sure copyrights are up to date as you review the changes prior to a 
commit.</p><h2 id="DeveloperBible-CommitMessages">Commit Messages</h2><p>Always 
provide a commit message. Howard generally tries to work off the JIRA, so his 
commit message is often:</p><blockquote><p>TAP5-1234: Make the Foo Widget more 
Ajax-tastic!</p></blockquote><p>It is <em>very important</em> to include the 
JIRA issue id in the commit. This is used in many places: JIRA links issues to 
the Git&#160;commits for that issue (very handy for seeing what changed as part 
o
 f a bug fix). The Hudson CI server does as well, and will actually link 
Git&#160;commits to issues after succesfully building.</p><h2 
id="DeveloperBible-JIRAProcedures">JIRA Procedures</h2><p>All Tapestry 
committers should be registerred with JIRA and part of the tapestry-developers 
JIRA group.</p><p>Every committer is invited to look at the list of <a  
class="external-link" 
href="https://issues.apache.org/jira/secure/IssueNavigator.jspa?mode=hide&amp;requestId=12317068";>'Review
 for closing'</a> issues and review them as it contains probably outdated or no 
more valid issues.</p><p>There's also a list of all <a  class="external-link" 
href="https://issues.apache.org/jira/secure/IssueNavigator.jspa?mode=hide&amp;requestId=12316792";>Open</a>
 issue about the project.</p><p>Ideally, we would always work top priortity to 
low priority. Howard sometimes jump out of order, if there's something cool to 
work on that fits in an available time slot. Alternately, you are always 
allowed to change t
 he priority of a bug before or as you work it.</p><p>As a general rule issues 
which are "<em>Invalid</em>" or "<em>Won't</em> <em>Fix</em>" shouldn't have a 
"<em>Fix</em> <em>version</em>".</p><h3 
id="DeveloperBible-Startingwork">Starting work</h3><p>When you start to work on 
an issue, make sure it is <em>assigned to you</em> and use the <em>start 
progress</em> option.</p><p>Add comments about the state of the fix, or the 
challenges in creating a fix. This often spurs the Issue's adder to<br 
clear="none"> provide more details.</p><p>Update the issue description to make 
it more legible and more precise if needed, i.e., "NPE in CheckUpdates" might 
become "NullPointerException when checking for updates to files that have been 
deleted". Verbose is good.</p><h3 id="DeveloperBible-Closingbugs">Closing 
bugs</h3><p>Is it a bug fix without tests? <strong>No.</strong> A good plan is 
to write a test that fails then work the code until the test passes. Often code 
works in a unit test but fails 
 unexpectedly in an integration test. As the G-Man says <em>"Expect unforeseen 
consequences"</em>.</p><p>When you check in a fix, you should 
<strong>close</strong> the issue and make sure the <strong>fix release</strong> 
is correct.</p><p>We're playing fast and loose &#8211; a better procedure would 
be to mark the bug resolved and verify the fix before closing it. That's ok, we 
have a community to double check our work <img class="emoticon emoticon-smile" 
src="https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png";
 data-emoticon-name="smile" alt="(smile)">.</p><p>For anything non-trivial, 
wait for the Hudson CI server to build. It catches a lot of things ... such as 
files that were not added to Git. And even IntelliJ has a bit of trouble with 
wildly refactored code. Hudson will catch all that.</p><h3 
id="DeveloperBible-Invalidissuesandduplicates">Invalid issues and 
duplicates</h3><p>Always provide comments about 
 why_ an issue is invalid (<em>"A Ruby implementation of Tapestry is out of 
scope for the project."</em>), or at least, a link to the duplicate 
issues.</p><p>Consider writing new tests to prove that an issue is not valid 
and then leave the tests in place &#8211; then close the bug as 
invalid.</p><p>Close the issue but <em>make sure the fix release is blank</em>. 
Otherwise, the issue <em>will be listed in the release notes</em>, which we 
don't want.</p><h2 id="DeveloperBible-Publicvs.Private/Internal">Public vs. 
Private/Internal</h2><p>This is a real big deal. As long as code is in the 
internal package, we have a high degree of carte-blanche to change it. As soon 
as code is public, we become handcuffed to backwards 
compatibility.</p><p><em>Interfaces are public, implementations are 
private</em>. You can see this is the bulk of the code, where 
org.apache.tapestry5.services is almost all interfaces and the implementations 
are in org.apache.tapestry5.internal.services.</p><p>Many more se
 rvices have both the interface and the implementation in 
org.apache.tapestry5.internal.services.</p><p>We absolutely <em>do not</em> 
want to make Page or ComponentPageElement public. You will often see public 
service facades that take a page name as a method parameter, and convert it to 
a page instance before invoking methods on internal services.</p><h2 
id="DeveloperBible-EvolvingComponents">Evolving Components</h2><p>We do not 
have a specific plan for this yet. Future Tapestry 5 will add features to allow 
clean renames of parameters, and a way to deprecated and eventually remove 
components.</p><h2 id="DeveloperBible-EvolvingInterfaces">Evolving 
Interfaces</h2><p>Tapestry uses interfaces quite extensively.</p><p>Interfaces 
fall into two categories: service interfaces called by user code, and 
interfaces implemented by user code.</p><p>Internal interfaces may be changed 
at any time. That's why so much is kept internal.</p><h3 
id="DeveloperBible-ServiceInterfaces">Service Interfaces</
 h3><p>New methods may be added if absolutely necessary, but this should be 
avoided if at all possible. Don't forget the <code>@since</code> Javadoc 
annotation.</p><p>Consider having a stable public facade service whose 
implementation calls into one or more internal service.</p><h3 
id="DeveloperBible-UserInterfaces">User Interfaces</h3><p>These should be 
frozen, no changes once released. Failure to do so causes <em>non-backwards 
compatible upgrade problems</em>; that is, classes that implement the (old) 
interface are suddenly invalid, missing methods from the (new) 
interface.</p><p>Consider introducing a new interface that extends the old one 
and adds new methods. Make sure you support both.</p><p>You can see this with 
ServiceDef and ServiceDef2 (which extends ServiceDef). Yes this can be a bit 
ugly.</p><p>Howard uses utility methods that convert from ServiceDef to 
ServiceDef2, adding a wrapper implementation around a ServiceDef instance if 
necessary:</p><plain-text-body>  public sta
 tic ServiceDef2 toServiceDef2(final ServiceDef sd)
+                <div id="ConfluenceContent"><p>IDE choices, coding style and 
formatting, commit practices, naming conventions and other issues relevant to 
Tapestry committers &amp; contributers.</p><div class="aui-label" 
style="float:right" title="Related Articles"><h3>Related Articles</h3><ul 
class="content-by-label"><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="building-tapestry-from-source.html">Building Tapestry from 
Source</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="version-numbers.html">Version Numbers</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="developer-bible.html">Developer Bible</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="release-process.html">Release Process</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="developer-information.html">Developer Information</a> 
+  </div> </li><li> 
+  <div> 
+   <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" 
title="Page">Page:</span> 
+  </div> 
+  <div class="details"> 
+   <a  href="confluence-site-setup.html">Confluence Site Setup</a> 
+  </div> </li></ul></div><h2 id="DeveloperBible-IDEChoices">IDE 
Choices</h2><h3 id="DeveloperBible-IntelliJ">IntelliJ</h3><p>It's a free 
license for all committers and it's just better. Yes, the first few days can be 
an unpleasant fumble because everything is almost, but not quite, familiar. 
Pretty soon you'll love IDEA and recognize that Eclipse has been bending you 
over and doing unspeakable things.</p><p>There are shared code formatting 
settings in the <a  class="external-link" 
href="https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree;f=support";>support
 directory</a> (idea-settings.jar). This will prevent unexpected conflicts due 
to formatting.</p><h3 id="DeveloperBible-Eclipse">Eclipse</h3><p>Howard uses 
this ... because he can't manage to switch IDEs constantly (he uses Eclipse for 
training). Lately its gotten better.</p><p>As with IntelliJ, there are shared 
code formatting settings for Eclipse in the <a  class="external-link" 
href="https://git-wip-us.apache.org/rep
 os/asf?p=tapestry-5.git;a=tree;f=support">support directory</a> 
(tapestry-indent-eclipse.xml).</p><h2 
id="DeveloperBible-Copyrights">Copyrights</h2><p>All source files should have 
the ASF copyright comment on top, except where such a comment would interfere 
with its behavior. For example, component template files omit the 
comment.</p><p>As you make changes to files, update the copyright to add the 
current year to the list. The goal is that the copyright notice includes the 
year in which files change. When creating a new file, don't back date the 
copyright year ... start with the current year. Try not to change the copyright 
year on files that haven't actually changed.</p><p>IntelliJ has a great 
comparison view: Cmd-9 to see the local changes, the Cmd-D to see the 
differences. You can whip through the changes (using Cmd-forward arrow) and 
make sure copyrights are up to date as you review the changes prior to a 
commit.</p><h2 id="DeveloperBible-CommitMessages">Commit Messages</h2><p>A
 lways provide a commit message. Howard generally tries to work off the JIRA, 
so his commit message is often:</p><blockquote><p>TAP5-1234: Make the Foo 
Widget more Ajax-tastic!</p></blockquote><p>It is <em>very important</em> to 
include the JIRA issue id in the commit. This is used in many places: JIRA 
links issues to the Git&#160;commits for that issue (very handy for seeing what 
changed as part of a bug fix). The Hudson CI server does as well, and will 
actually link Git&#160;commits to issues after succesfully building.</p><h2 
id="DeveloperBible-JIRAProcedures">JIRA Procedures</h2><p>All Tapestry 
committers should be registerred with JIRA and part of the tapestry-developers 
JIRA group.</p><p>Every committer is invited to look at the list of <a  
class="external-link" 
href="https://issues.apache.org/jira/secure/IssueNavigator.jspa?mode=hide&amp;requestId=12317068";>'Review
 for closing'</a> issues and review them as it contains probably outdated or no 
more valid issues.</p><p>There's a
 lso a list of all <a  class="external-link" 
href="https://issues.apache.org/jira/secure/IssueNavigator.jspa?mode=hide&amp;requestId=12316792";>Open</a>
 issue about the project.</p><p>Ideally, we would always work top priortity to 
low priority. Howard sometimes jump out of order, if there's something cool to 
work on that fits in an available time slot. Alternately, you are always 
allowed to change the priority of a bug before or as you work it.</p><p>As a 
general rule issues which are "<em>Invalid</em>" or "<em>Won't</em> 
<em>Fix</em>" shouldn't have a "<em>Fix</em> <em>version</em>".</p><h3 
id="DeveloperBible-Startingwork">Starting work</h3><p>When you start to work on 
an issue, make sure it is <em>assigned to you</em> and use the <em>start 
progress</em> option.</p><p>Add comments about the state of the fix, or the 
challenges in creating a fix. This often spurs the Issue's adder to<br 
clear="none"> provide more details.</p><p>Update the issue description to make 
it more legible and m
 ore precise if needed, i.e., "NPE in CheckUpdates" might become 
"NullPointerException when checking for updates to files that have been 
deleted". Verbose is good.</p><h3 id="DeveloperBible-Closingbugs">Closing 
bugs</h3><p>Is it a bug fix without tests? <strong>No.</strong> A good plan is 
to write a test that fails then work the code until the test passes. Often code 
works in a unit test but fails unexpectedly in an integration test. As the 
G-Man says <em>"Expect unforeseen consequences"</em>.</p><p>When you check in a 
fix, you should <strong>close</strong> the issue and make sure the <strong>fix 
release</strong> is correct.</p><p>We're playing fast and loose &#8211; a 
better procedure would be to mark the bug resolved and verify the fix before 
closing it. That's ok, we have a community to double check our work <img 
class="emoticon emoticon-smile" 
src="https://cwiki.apache.org/confluence/s/en_GB/5982/f2b47fb3d636c8bc9fd0b11c0ec6d0ae18646be7.1/_/images/icons/emoticons/smile.png";
 data-
 emoticon-name="smile" alt="(smile)">.</p><p>For anything non-trivial, wait for 
the Hudson CI server to build. It catches a lot of things ... such as files 
that were not added to Git. And even IntelliJ has a bit of trouble with wildly 
refactored code. Hudson will catch all that.</p><h3 
id="DeveloperBible-Invalidissuesandduplicates">Invalid issues and 
duplicates</h3><p>Always provide comments about why_ an issue is invalid 
(<em>"A Ruby implementation of Tapestry is out of scope for the 
project."</em>), or at least, a link to the duplicate issues.</p><p>Consider 
writing new tests to prove that an issue is not valid and then leave the tests 
in place &#8211; then close the bug as invalid.</p><p>Close the issue but 
<em>make sure the fix release is blank</em>. Otherwise, the issue <em>will be 
listed in the release notes</em>, which we don't want.</p><h2 
id="DeveloperBible-Publicvs.Private/Internal">Public vs. 
Private/Internal</h2><p>This is a real big deal. As long as code is in the 
intern
 al package, we have a high degree of carte-blanche to change it. As soon as 
code is public, we become handcuffed to backwards 
compatibility.</p><p><em>Interfaces are public, implementations are 
private</em>. You can see this is the bulk of the code, where 
org.apache.tapestry5.services is almost all interfaces and the implementations 
are in org.apache.tapestry5.internal.services.</p><p>Many more services have 
both the interface and the implementation in 
org.apache.tapestry5.internal.services.</p><p>We absolutely <em>do not</em> 
want to make Page or ComponentPageElement public. You will often see public 
service facades that take a page name as a method parameter, and convert it to 
a page instance before invoking methods on internal services.</p><h2 
id="DeveloperBible-EvolvingComponents">Evolving Components</h2><p>We do not 
have a specific plan for this yet. Future Tapestry 5 will add features to allow 
clean renames of parameters, and a way to deprecated and eventually remove 
component
 s.</p><h2 id="DeveloperBible-EvolvingInterfaces">Evolving 
Interfaces</h2><p>Tapestry uses interfaces quite extensively.</p><p>Interfaces 
fall into two categories: service interfaces called by user code, and 
interfaces implemented by user code.</p><p>Internal interfaces may be changed 
at any time. That's why so much is kept internal.</p><h3 
id="DeveloperBible-ServiceInterfaces">Service Interfaces</h3><p>New methods may 
be added if absolutely necessary, but this should be avoided if at all 
possible. Don't forget the <code>@since</code> Javadoc 
annotation.</p><p>Consider having a stable public facade service whose 
implementation calls into one or more internal service.</p><h3 
id="DeveloperBible-UserInterfaces">User Interfaces</h3><p>These should be 
frozen, no changes once released. Failure to do so causes <em>non-backwards 
compatible upgrade problems</em>; that is, classes that implement the (old) 
interface are suddenly invalid, missing methods from the (new) 
interface.</p><p>Consider 
 introducing a new interface that extends the old one and adds new methods. 
Make sure you support both.</p><p>You can see this with ServiceDef and 
ServiceDef2 (which extends ServiceDef). Yes this can be a bit 
ugly.</p><p>Howard uses utility methods that convert from ServiceDef to 
ServiceDef2, adding a wrapper implementation around a ServiceDef instance if 
necessary:</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 ServiceDef2 toServiceDef2(final 
ServiceDef sd)
   {
     if (sd instanceof ServiceDef2)
         return (ServiceDef2) sd;
@@ -87,7 +119,8 @@
         . . .
     };
   }
-</plain-text-body><h2 id="DeveloperBible-Useof@since">Use of 
@since</h2><p>When adding new classes or interface, or adding new methods to 
existing types, add an @since Javadoc comment.</p><p>Use the complete version 
number of the release in which the type or method was added: i.e., <em>@since 
5.1.0.3</em>.</p><h2 id="DeveloperBible-CodeStyle&amp;Formatting">Code Style 
&amp; Formatting</h2><p>Yes, at one time Howard used leading underscores for 
field names. He has since changed my mind, but this unfortunately infected 
other people; please try to make your code blend in when modifying existing 
source.</p><p>Long ago, Tapestry (3) code used the regrettable 
"leading-I-on-interfaces" style. Don't do that. Instead, name the 
implementation class with an "Impl" at the end.</p><p>Howard prefers braces on 
a new line (and thus, open braces lined up with close braces), so that's what 
the default code formatting is set up for. It's okay to omit braces for trivial 
one-liner if statements, such as
  <code>if (!test) return;</code>.</p><p>Indent with 4 spaces instead of 
tabs.</p><p>Use a lot of vertical whitespace to break methods into logical 
sections.</p><p>We're coding Java, not Pascal; it's better to have a few checks 
early on with quick returns or exceptions than have ten-levels deep block 
nesting just so a method can have a single return statement. In other words, 
<em>else considered harmful</em>. Low code complexity is better, more readable, 
more maintainable code.</p><p>Don't bother alphabetizing things, because the 
IDE lets you jump around easily.</p><p><em>Final is the new private.</em> Final 
fields are great for multi-threaded code. Especially when creating service 
implementations with dependencies, store those dependencies into final fields. 
Once we're all running on 100 core workstations, you'll thank me. Seriously, 
Java's memory model is seriously twisted stuff, and assigning to a non-final 
field from a constructor opens up a tiny window of non-thread safety.</p><
 h2 id="DeveloperBible-Comments">Comments</h2><p>Comments are overwhelmingly 
important. Try to capture the <em>why</em> of a class or method. Add lots of 
links, to code that will be invoked by the method, to related methods or 
classes, and so forth. For instance, you may often have an annotation, a worker 
class for the annotation, and a related service all cross-linked.</p><p>Comment 
the <em>interfaces</em> and don't get worked up on the 
<em>implementations</em>. Javadoc does a perfectly good job of copying 
interface comments to implementations, so this falls under the <em>Don't Repeat 
Yourself</em> guideline.</p><p>Be very careful about documenting what methods 
can accept null, and what methods may return null. Generally speaking, people 
will assume that null is not allowed for parameters, and method will never 
return null, unless it is explicitly documented that null is allowed (or 
potentially returned).</p><h2 
id="DeveloperBible-Documentation">Documentation</h2><p>Try and keep the
  documentation up-to date as you make changes; it is <em>much</em> harder to 
do so later. This is now much easier using the Confluence wiki (you're reading 
the result <img class="emoticon emoticon-smile" 
src="https://cwiki.apache.org/confluence/s/en_GB/5997/6f42626d00e36f53fe51440403446ca61552e2a2.1/_/images/icons/emoticons/smile.png";
 data-emoticon-name="smile" alt="(smile)">).</p><p>Documentation was at one 
point the <em>#1 criticism</em> of Tapestry!</p><h2 
id="DeveloperBible-ClassandMethodNamingConventions">Class and Method Naming 
Conventions</h2><p>Naming things is hard. Names that make sense to one person 
won't to another.</p><p>That being said, Howard has tried to be somewhat 
consistent with naming. Not perfectly.</p><h3 
id="DeveloperBible-Factory,Creator">Factory, Creator</h3><p>A factory class 
creates new objects. Methods will often be prefixed with "create" or "new". 
Don't expect a Factory to cache anything, it just creates new things.</p><h3 
id="DeveloperBible-Source">Sour
 ce</h3><p>A source is a level up from a Factory. It <em>may</em> combine 
multiple factories together. It <em>usually</em> will cache the result. Method 
are often prefixed with "get".</p><h3 id="DeveloperBible-Findvs.Get">Find vs. 
Get</h3><p>For methods: A "find" prefix indicates that a non-match is valid and 
null may be returned. A "get" prefix indicates that a non-match is invalid and 
an exception will be thrown in that case (and null will never be 
returned).</p><h3 id="DeveloperBible-Contribution">Contribution</h3><p>A data 
object usually associated with a Tapestry IoC service's configuration.</p><h3 
id="DeveloperBible-Filter">Filter</h3><p>Part of a pipeline, where there's an 
associated main interface, and the Filter wraps around that main interface. 
Each main interface method is duplicated in the Filter, with an extra parameter 
used to chain the interface.</p><h3 
id="DeveloperBible-Manager">Manager</h3><p>Often a wrapper around a service 
configuration, it provides access to the 
 contributed values (possibly after some transformation).</p><h3 
id="DeveloperBible-To">To</h3><p>A method prefix that indicates a conversion or 
coersion from one type to another. I.e., 
<code>toUserPresentable()</code>.</p><h3 
id="DeveloperBible-Worker">Worker</h3><p>An object that peforms a specific job. 
Workers will be stateless, but will be passed a stateful object to perform some 
operation upon.</p><h3 id="DeveloperBible-Builder">Builder</h3><p>An object 
whose job is to create other objects, typically in the context of creating a 
core service implementation for a Tapestry IoC service (such as PipelineBuilder 
or ChainBuilder).</p><h3 id="DeveloperBible-Support">Support</h3><p>An object 
that provides supporting operations to other objects; this is a kind of "loose 
aggregation".</p><h3 id="DeveloperBible-Parameters">Parameters</h3><p>A data 
object that holds a number of related values that would otherwise be separate 
parameter values to a method. This tends to streamline code (espec
 ially when using a Filter interface) and allows the parameters to be evolved 
without changing the method signature.</p><h3 
id="DeveloperBible-Strategy">Strategy</h3><p>An object that "plugs into" some 
other code, allowing certain decisions to be deferred to the Strategy. Often a 
Strategy is selected based on the type of some object being operated 
upon.</p><h3 id="DeveloperBible-Context">Context</h3><p>Captures some stateful 
information that may be passed around between stateless services.</p><h3 
id="DeveloperBible-Constants">Constants</h3><p>A non-instantiable class that 
contains public static fields that are referenced in multiple places.</p><h3 
id="DeveloperBible-Hub">Hub</h3><p>An object that allows listeners to be 
registered. Often includes a method prefixed with "trigger" that will send 
notifications to listeners.</p><h2 
id="DeveloperBible-ImplementtoString()">Implement 
<code>toString()</code></h2><p>Objects that are exposed to user code should 
generally implement a meaningful 
 toString() method. And that method should be tested.</p><h2 
id="DeveloperBible-Subclassing">Subclassing</h2><p>You'll notice there isn't a 
lot of inheritance in Tapestry. Given the function of the IoC container, it is 
much more common to use some variation of <em>aggregation</em> rather than 
<em>inheritance</em>.</p><p>Where subclassing exists, the guideline for 
constructor parameters is: the subclass should include all the constructor 
parameters of the superclass, in the same positions. Thus subclass constructor 
parameters are appended to the list of super-class constructor 
parameters.</p></div>
+</pre>
+</div></div><h2 id="DeveloperBible-Useof@since">Use of @since</h2><p>When 
adding new classes or interface, or adding new methods to existing types, add 
an @since Javadoc comment.</p><p>Use the complete version number of the release 
in which the type or method was added: i.e., <em>@since 5.1.0.3</em>.</p><h2 
id="DeveloperBible-CodeStyle&amp;Formatting">Code Style &amp; 
Formatting</h2><p>Yes, at one time Howard used leading underscores for field 
names. He has since changed my mind, but this unfortunately infected other 
people; please try to make your code blend in when modifying existing 
source.</p><p>Long ago, Tapestry (3) code used the regrettable 
"leading-I-on-interfaces" style. Don't do that. Instead, name the 
implementation class with an "Impl" at the end.</p><p>Howard prefers braces on 
a new line (and thus, open braces lined up with close braces), so that's what 
the default code formatting is set up for. It's okay to omit braces for trivial 
one-liner if statements, such as <code
 >if (!test) return;</code>.</p><p>Indent with 4 spaces instead of 
 >tabs.</p><p>Use a lot of vertical whitespace to break methods into logical 
 >sections.</p><p>We're coding Java, not Pascal; it's better to have a few 
 >checks early on with quick returns or exceptions than have ten-levels deep 
 >block nesting just so a method can have a single return statement. In other 
 >words, <em>else considered harmful</em>. Low code complexity is better, more 
 >readable, more maintainable code.</p><p>Don't bother alphabetizing things, 
 >because the IDE lets you jump around easily.</p><p><em>Final is the new 
 >private.</em> Final fields are great for multi-threaded code. Especially when 
 >creating service implementations with dependencies, store those dependencies 
 >into final fields. Once we're all running on 100 core workstations, you'll 
 >thank me. Seriously, Java's memory model is seriously twisted stuff, and 
 >assigning to a non-final field from a constructor opens up a tiny window of 
 >non-thread safety.</p><h2 id=
 "DeveloperBible-Comments">Comments</h2><p>Comments are overwhelmingly 
important. Try to capture the <em>why</em> of a class or method. Add lots of 
links, to code that will be invoked by the method, to related methods or 
classes, and so forth. For instance, you may often have an annotation, a worker 
class for the annotation, and a related service all cross-linked.</p><p>Comment 
the <em>interfaces</em> and don't get worked up on the 
<em>implementations</em>. Javadoc does a perfectly good job of copying 
interface comments to implementations, so this falls under the <em>Don't Repeat 
Yourself</em> guideline.</p><p>Be very careful about documenting what methods 
can accept null, and what methods may return null. Generally speaking, people 
will assume that null is not allowed for parameters, and method will never 
return null, unless it is explicitly documented that null is allowed (or 
potentially returned).</p><h2 
id="DeveloperBible-Documentation">Documentation</h2><p>Try and keep the docum
 entation up-to date as you make changes; it is <em>much</em> harder to do so 
later. This is now much easier using the Confluence wiki (you're reading the 
result <img class="emoticon emoticon-smile" 
src="https://cwiki.apache.org/confluence/s/en_GB/5982/f2b47fb3d636c8bc9fd0b11c0ec6d0ae18646be7.1/_/images/icons/emoticons/smile.png";
 data-emoticon-name="smile" alt="(smile)">).</p><p>Documentation was at one 
point the <em>#1 criticism</em> of Tapestry!</p><h2 
id="DeveloperBible-ClassandMethodNamingConventions">Class and Method Naming 
Conventions</h2><p>Naming things is hard. Names that make sense to one person 
won't to another.</p><p>That being said, Howard has tried to be somewhat 
consistent with naming. Not perfectly.</p><h3 
id="DeveloperBible-Factory,Creator">Factory, Creator</h3><p>A factory class 
creates new objects. Methods will often be prefixed with "create" or "new". 
Don't expect a Factory to cache anything, it just creates new things.</p><h3 
id="DeveloperBible-Source">Source</h3
 ><p>A source is a level up from a Factory. It <em>may</em> combine multiple 
 >factories together. It <em>usually</em> will cache the result. Method are 
 >often prefixed with "get".</p><h3 id="DeveloperBible-Findvs.Get">Find vs. 
 >Get</h3><p>For methods: A "find" prefix indicates that a non-match is valid 
 >and null may be returned. A "get" prefix indicates that a non-match is 
 >invalid and an exception will be thrown in that case (and null will never be 
 >returned).</p><h3 id="DeveloperBible-Contribution">Contribution</h3><p>A data 
 >object usually associated with a Tapestry IoC service's configuration.</p><h3 
 >id="DeveloperBible-Filter">Filter</h3><p>Part of a pipeline, where there's an 
 >associated main interface, and the Filter wraps around that main interface. 
 >Each main interface method is duplicated in the Filter, with an extra 
 >parameter used to chain the interface.</p><h3 
 >id="DeveloperBible-Manager">Manager</h3><p>Often a wrapper around a service 
 >configuration, it provides access to the contri
 buted values (possibly after some transformation).</p><h3 
id="DeveloperBible-To">To</h3><p>A method prefix that indicates a conversion or 
coersion from one type to another. I.e., 
<code>toUserPresentable()</code>.</p><h3 
id="DeveloperBible-Worker">Worker</h3><p>An object that peforms a specific job. 
Workers will be stateless, but will be passed a stateful object to perform some 
operation upon.</p><h3 id="DeveloperBible-Builder">Builder</h3><p>An object 
whose job is to create other objects, typically in the context of creating a 
core service implementation for a Tapestry IoC service (such as PipelineBuilder 
or ChainBuilder).</p><h3 id="DeveloperBible-Support">Support</h3><p>An object 
that provides supporting operations to other objects; this is a kind of "loose 
aggregation".</p><h3 id="DeveloperBible-Parameters">Parameters</h3><p>A data 
object that holds a number of related values that would otherwise be separate 
parameter values to a method. This tends to streamline code (especially 
 when using a Filter interface) and allows the parameters to be evolved without 
changing the method signature.</p><h3 
id="DeveloperBible-Strategy">Strategy</h3><p>An object that "plugs into" some 
other code, allowing certain decisions to be deferred to the Strategy. Often a 
Strategy is selected based on the type of some object being operated 
upon.</p><h3 id="DeveloperBible-Context">Context</h3><p>Captures some stateful 
information that may be passed around between stateless services.</p><h3 
id="DeveloperBible-Constants">Constants</h3><p>A non-instantiable class that 
contains public static fields that are referenced in multiple places.</p><h3 
id="DeveloperBible-Hub">Hub</h3><p>An object that allows listeners to be 
registered. Often includes a method prefixed with "trigger" that will send 
notifications to listeners.</p><h2 
id="DeveloperBible-ImplementtoString()">Implement 
<code>toString()</code></h2><p>Objects that are exposed to user code should 
generally implement a meaningful toStri
 ng() method. And that method should be tested.</p><h2 
id="DeveloperBible-Subclassing">Subclassing</h2><p>You'll notice there isn't a 
lot of inheritance in Tapestry. Given the function of the IoC container, it is 
much more common to use some variation of <em>aggregation</em> rather than 
<em>inheritance</em>.</p><p>Where subclassing exists, the guideline for 
constructor parameters is: the subclass should include all the constructor 
parameters of the superclass, in the same positions. Thus subclass constructor 
parameters are appended to the list of super-class constructor 
parameters.</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: 
websites/production/tapestry/content/documentation-improvement-tasks.html
==============================================================================
--- websites/production/tapestry/content/documentation-improvement-tasks.html 
(original)
+++ websites/production/tapestry/content/documentation-improvement-tasks.html 
Wed Sep 20 12:29:16 2017
@@ -27,6 +27,16 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
+    <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
+        <script>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -69,34 +79,55 @@
       <div id="content">
                 <div id="ConfluenceContent"><p>This is an informal list of 
suggested improvements to the Tapestry 5 site documentation &#8211; things to 
work on soon.  Most of these have come from users on the Tapestry Users mailing 
list.</p>
 
-<plain-text-body>{float:right|background=#eee}
-{contentbylabel:title=Related 
Articles|showLabels=false|showSpace=false|labels=plans}
-{float}</plain-text-body>
-
-<rich-text-body>
-<p>These are merely suggestions from Tapestry users.  Some might be bad ideas. 
 Consider carefully which of these ought to be done and how, and start a 
discussion on the dev mailing list about any change that could be 
controversial.</p></rich-text-body>
-
-<plain-text-body>||Completed||Priority||Locked||CreatedDate||CompletedDate||Assignee||Name||
-|F|H|F|          |          | |Need more cross-linking between the wiki pages, 
especially between FAQ pages, User Guide pages, Cheat Sheet pages and Cookbook 
pages that cover the same topic.|
-|F|M|F|          |          | |[Component Cheat Sheet] should have, for each 
of the listed annotations, a link to the corresponding API page.|
-|F|M|F|          |          | |Some pages don't link to all of their child 
pages|
-|F|M|F|          |          | |Move some of the best MoinMoin wiki content 
into Confluence?|
-|F|M|F|1290869296693|          | |Need an article on clustering &amp; high 
availability, then link to it from the clustering sections of [Persistent Page 
Data], [IoC - serialization], [Persistent State], [HTTPS], and other pages that 
mention clustering|
-|F|M|F|1290869418470|          | |Need a "Support" page that lists support 
options.  This is where the mailing lists should be mentioned., as well as 
Howard's trainig, etc|
-|F|M|F|1290872794706|          | |The links to "Tapestry Home" in the 
breadcrums on pages like [Tutorial] link to the "Home" page but should link to 
the index.html page|
-|F|M|F|1290872892940|          | |Make it more obvious how to contribute to 
documentation improvements|
-|T|M|F|1290873286462|1291053687265|[email protected]|in the "create your 
first tapestry project" tutorial, don't make the user choose an archetype or a 
tapestry version. Write the instructions for the latest stable version. It's 
better to have that be out of date when a new version comes out (because it 
still will work) than have the user decide at this stage. Same for the groupId, 
artifactId, version and package. It's a test project the user is creating, 
those values are not going to matter. Give the defaults so people can copy and 
paste the command and have the project created, built and run.|
-|T|M|F|1290873334655|1291036593723|[email protected]|After the test 
project has been created, give the user some pointers on where to find things 
(pages go in src/main/java/com/example/pages, page templates go in webapp). 
Although there is a link to the tutorial, if this first experience is too 
frustrating, people might not even bother to go there.|
-|F|M|F|1290873345788|          | |add something to the archetype with 
commented out code that the user can uncomment and see something cool happen. 
It has to be a few lines only, to be easily understandable, and clearly link 
components in the template with their methods in the page class.|
-|F|M|F|1290873360243|          | |the tapestry tutorial starts unnecessarily 
verbose about topics not really related to me getting code running and out the 
door. Strip it to the essentials. If you want to mention Struts and the Servlet 
API compared to the tapestry way, mention them in a separate chapter so they 
are easy to find / skip as needed.|
-|F|M|F|1290873372769|          | |there is no table of contents for the 
tutorial and no indication of how long it takes to complete|
-|F|M|F|1290873390989|          | |There are too many callouts, warnings and 
decorations in the tutorial. It is very distracting visually and that makes it 
hard to follow. It's impossible to scan the pages to get a feel for what you've 
got ahead of you.|
-|F|M|F|1290873483266|          | |Add a page about testing your Tapestry app 
(not just testing of pages)|
-|F|M|F|1290873573643|          | |On the ComponentCheetSheet, add a sentance 
or two more on each annotation would be great.|
-|T|M|F|1290873630472|1418608629709|bobharner|The tutorial Setting up your 
environment should be improved. Alternatives should be described on how to run 
T5 apps in the Eclipse or other IDEs, but not in the text as that would make it 
too long. I think there should be links for alternative setups - like how to 
run the T5 app from a main class and even start VisualVM for early debugging 
and optimizing (each alternative has pros and cons). There is no mention of 
m2eclipse plugin. Of course one can use JDK 6 also - only 1.5 is there. There 
is a sentence: "You should not have to download this directly". Why are then 
download links on the download page and no mention of maven at the same time. 
It is confusing for newbs.|
-|F|M|F|1290873682697|          | |Add a link to JIRA in the About page|
-|F|M|F|1290954416064|          | |Resolve the TODO at the bottom of [Component 
Classes] ("May want a more complex check; what if user uses prop: in the 
template and there's a conflict?")|
-</plain-text-body></div>
+<div class="navmenu" style="float:right; background:#eee; margin:3px; 
padding:3px">
+<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>
+
+<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>These are merely suggestions from Tapestry users.  Some might be bad ideas. 
 Consider carefully which of these ought to be done and how, and start a 
discussion on the dev mailing list about any change that could be 
controversial.</p></div></div>
+
+<div style="background-color: #f9f9f9; border: 1px solid #c0c0c0; width: 
40em;">
+    <h2></h2>
+    <h6>15% of the tasks completed</h6>
+    <table border="0" style="border-collapse: collapse; width: 
100%;"><tbody><tr><td colspan="1" rowspan="1" style="border-top: 1px solid 
#cbcbcb; width: 10%;"><input disabled></td><td colspan="1" rowspan="1" 
style="border-top: 1px solid #cbcbcb; width: 70%">Need more cross-linking 
between the wiki pages, especially between FAQ pages, User Guide pages, Cheat 
Sheet pages and Cookbook pages that cover the same topic.</td><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 20%; text-align: 
right;">
+                                                    High
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%"><a  href="component-cheat-sheet.html" title="Component Cheat 
Sheet">Component Cheat Sheet</a> should have, for each of the listed 
annotations, a link to the corresponding API page.</td><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 20%; text-align: 
right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">Some pages don't link to all of their child pages</td><td 
colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; width: 20%; 
text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">Move some of the best MoinMoin wiki content into 
Confluence?</td><td colspan="1" rowspan="1" style="border-top: 1px solid 
#cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">Need an article on clustering &amp; high availability, then link to 
it from the clustering sections of <a  href="persistent-page-data.html" 
title="Persistent Page Data">Persistent Page Data</a>, <a  
href="ioc-serialization.html" title="IoC - serialization">IoC - 
serialization</a>, <a  href="persistent-state.html" title="Persistent 
State">Persistent State</a>, <a  href="https.html" title="HTTPS">HTTPS</a>, and 
other pages that mention clustering</td><td colspan="1" rowspan="1" 
style="border-top: 1px solid #cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">Need a "Support" page that lists support options.  This is where 
the mailing lists should be mentioned., as well as Howard's trainig, 
etc</td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">The links to "Tapestry Home" in the breadcrums on pages like <a  
href="tutorial.html" title="Tutorial">Tutorial</a> link to the "Home" page but 
should link to the index.html page</td><td colspan="1" rowspan="1" 
style="border-top: 1px solid #cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">Make it more obvious how to contribute to documentation 
improvements</td><td colspan="1" rowspan="1" style="border-top: 1px solid 
#cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
checked></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">in the "create your first tapestry project" tutorial, don't make 
the user choose an archetype or a tapestry version. Write the instructions for 
the latest stable version. It's better to have that be out of date when a new 
version comes out (because it still will work) than have the user decide at 
this stage. Same for the groupId, artifactId, version and package. It's a test 
project the user is creating, those values are not going to matter. Give the 
defaults so people can copy and paste the command and have the project created, 
built and run.</td><td colspan="1" rowspan="1" style="border-top: 1px solid 
#cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
checked></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">After the test project has been created, give the user some 
pointers on where to find things (pages go in src/main/java/com/example/pages, 
page templates go in webapp). Although there is a link to the tutorial, if this 
first experience is too frustrating, people might not even bother to go 
there.</td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">add something to the archetype with commented out code that the 
user can uncomment and see something cool happen. It has to be a few lines 
only, to be easily understandable, and clearly link components in the template 
with their methods in the page class.</td><td colspan="1" rowspan="1" 
style="border-top: 1px solid #cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">the tapestry tutorial starts unnecessarily verbose about topics not 
really related to me getting code running and out the door. Strip it to the 
essentials. If you want to mention Struts and the Servlet API compared to the 
tapestry way, mention them in a separate chapter so they are easy to find / 
skip as needed.</td><td colspan="1" rowspan="1" style="border-top: 1px solid 
#cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">there is no table of contents for the tutorial and no indication of 
how long it takes to complete</td><td colspan="1" rowspan="1" 
style="border-top: 1px solid #cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">There are too many callouts, warnings and decorations in the 
tutorial. It is very distracting visually and that makes it hard to follow. 
It's impossible to scan the pages to get a feel for what you've got ahead of 
you.</td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">Add a page about testing your Tapestry app (not just testing of 
pages)</td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">On the ComponentCheetSheet, add a sentance or two more on each 
annotation would be great.</td><td colspan="1" rowspan="1" style="border-top: 
1px solid #cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
checked></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">The tutorial Setting up your environment should be improved. 
Alternatives should be described on how to run T5 apps in the Eclipse or other 
IDEs, but not in the text as that would make it too long. I think there should 
be links for alternative setups - like how to run the T5 app from a main class 
and even start VisualVM for early debugging and optimizing (each alternative 
has pros and cons). There is no mention of m2eclipse plugin. Of course one can 
use JDK 6 also - only 1.5 is there. There is a sentence: "You should not have 
to download this directly". Why are then download links on the download page 
and no mention of maven at the same time. It is confusing for newbs.</td><td 
colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; width: 20%; te
 xt-align: right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">Add a link to JIRA in the About page</td><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 20%; text-align: 
right;">
+                                                    Medium
+                                            </td></tr><tr><td colspan="1" 
rowspan="1" style="border-top: 1px solid #cbcbcb; width: 10%;"><input 
disabled></td><td colspan="1" rowspan="1" style="border-top: 1px solid #cbcbcb; 
width: 70%">Resolve the TODO at the bottom of <a  href="component-classes.html" 
title="Component Classes">Component Classes</a> ("May want a more complex 
check; what if user uses prop: in the template and there's a 
conflict?")</td><td colspan="1" rowspan="1" style="border-top: 1px solid 
#cbcbcb; width: 20%; text-align: right;">
+                                                    Medium
+                                            </td></tr></tbody></table>
+</div></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/dom.html
==============================================================================
--- websites/production/tapestry/content/dom.html (original)
+++ websites/production/tapestry/content/dom.html Wed Sep 20 12:29:16 2017
@@ -27,6 +27,16 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
+    <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
+        <script>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,13 +77,14 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><h1 
id="DOM-DocumentObjectModel">Document Object Model</h1><p>Tapestry 5 takes a 
very different approach to markup generation than most other frameworks. 
Components render out a Document Object Model (DOM). This is a tree of nodes 
representing elements, attributes and text within a document.</p><p>Once all 
rendering is complete, the DOM tree is streamed to the client.</p><p>The <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/MarkupWriter.html";>MarkupWriter</a>
 interface allows the majority of component code to treat the generation of 
output as a stream. In reality, MarkupWriter is more like a cursor into the DOM 
tree, and the DOM may ultimately be operated upon in a random access manner 
(rather than the serial (or buffered) approach used in Tapestry 
4).</p><plain-text-body>{float:right|width=30%}
-{info:title=A Note For Tapestry 4 Users}
-In Tapestry 4, markup generation was based on generating a character stream. 
At the lowest level, the fact that the output was in a markup format such as 
HTML, XHTML or WML was not known. Higher levels, such as the IMarkupWriter 
interface (and its implementations) provide the concept of markup generation: 
elements, attributes, start tags and end tags. This technique breaks down when 
two elements are peers, and not in a parent/child relationship. For example, 
the rendering of a FieldLabel component is affected by its companion TextField 
component. Handling these cases in Tapestry 4 required a number of kludges and 
special cases.
-{info}
-{float}</plain-text-body><h1 id="DOM-DOMClasses">DOM Classes</h1><p>The 
implementation of this DOM is part of Tapestry, despite the fact that several 
third-party alternatives exist. This represents a desire to limit dependencies 
for the framework, but also the Tapestry DOM is streamlined for initial 
creation, and a limited amount of subsequent modification. Most DOM 
implementations are more sophisticated than needed for Tapestry, with greater 
support for querying (often using XPath) and manipulation.</p><p>Once the 
Document object is created, you don't directly create new DOM objects; instead, 
each DOM object includes methods that create new sub-objects. This primarily 
applies to the Element class, which can be a container of text, comments and 
other elements.</p><h2 id="DOM-Document">Document</h2><p>The <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/dom/Document.html";>Document
 Object</a> represents the an entire document, which is to
  say, an entire response to be sent to the client.</p><p>Documents will have a 
single root element. The newRootElement() method is used to create the root 
element for the document.</p><p>The Document class also has methods for setting 
and getting the DTD, adding comments and text, and finding an element based on 
a path of element names.</p><h2 id="DOM-Element">Element</h2><p>An <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/dom/Element.html";>Element
 Object</a> represents an element of the document. Elements may have 
attributes, and they may themselves contain other elements, as well as text and 
comments.</p><p>The Element class has methods for searching, traversing and 
manipulating the DOM after it is built.</p><h1 
id="DOM-DOMManipulation/Rewriting">DOM Manipulation/Rewriting</h1><p>A powerful 
feature of Tapestry 5 is the ability to manipulate the structure and ordering 
of the DOM after it has been rendered. For example, this can be u
 sed to alter the output of a component that may otherwise be outside of your 
control.</p><p>DOM manipulation is surprisingly fast, too.</p><p>Methods on 
Node (and Element, which is a subclass of Node) allow an existing node to be 
moved relative to an Element. Nodes may be moved before or after the Element, 
or may be moved inside an Element at the top (the first child) or the bottom 
(the last child).</p><p>Element's <code>attribute</code> method adds a new 
attribute name/value pair to the Element. If an existing attribute with the 
specified name already exists, then then the new value is ignored. This has 
implications when different pieces of code try to add attributes to an Element 
... the first to add an attribute will "win". Conversely, the 
<code>forceAttributes</code> method can be used to update or remove an 
attribute.</p><p>In addition, the children of an Element may be removed or a 
Node (and all of its children) removed entirely.</p><p>Finally, an Element may 
"pop": the Elemen
 t is removed and replaced with its children.</p><h1 
id="DOM-MarkupWriter">MarkupWriter</h1><p>The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/MarkupWriter.html";>MarkupWriter
 interface</a> allows the structure of the document to be built while 
maintaining a streaming metaphor.</p><h2 
id="DOM-element()andend()methods">element() and end() methods</h2><p>Calls to 
element() create a new element within the tree, and may provide attributes for 
the new element as well. Calls to write(), writeln() and writef() write text 
nodes within the current element. <em>Every call to element() should be matched 
with a call to end()</em>, which is used to move the current node up one 
level.</p><parameter ac:name="">java</parameter><plain-text-body>  
writer.element("img", "src", "icon.png", "width", 20, "height", 20, alt, "*");
+                <div id="ConfluenceContent"><h1 
id="DOM-DocumentObjectModel">Document Object Model</h1><p>Tapestry 5 takes a 
very different approach to markup generation than most other frameworks. 
Components render out a Document Object Model (DOM). This is a tree of nodes 
representing elements, attributes and text within a document.</p><p>Once all 
rendering is complete, the DOM tree is streamed to the client.</p><p>The <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/MarkupWriter.html";>MarkupWriter</a>
 interface allows the majority of component code to treat the generation of 
output as a stream. In reality, MarkupWriter is more like a cursor into the DOM 
tree, and the DOM may ultimately be operated upon in a random access manner 
(rather than the serial (or buffered) approach used in Tapestry 4).</p><div 
class="navmenu" style="float:right; width:30%; background:white; margin:3px; 
padding:3px">
+<div class="confluence-information-macro 
confluence-information-macro-information"><p class="title">A Note For Tapestry 
4 Users</p><span class="aui-icon aui-icon-small aui-iconfont-info 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body">
+<p>In Tapestry 4, markup generation was based on generating a character 
stream. At the lowest level, the fact that the output was in a markup format 
such as HTML, XHTML or WML was not known. Higher levels, such as the 
IMarkupWriter interface (and its implementations) provide the concept of markup 
generation: elements, attributes, start tags and end tags. This technique 
breaks down when two elements are peers, and not in a parent/child 
relationship. For example, the rendering of a FieldLabel component is affected 
by its companion TextField component. Handling these cases in Tapestry 4 
required a number of kludges and special cases.</p></div></div></div><h1 
id="DOM-DOMClasses">DOM Classes</h1><p>The implementation of this DOM is part 
of Tapestry, despite the fact that several third-party alternatives exist. This 
represents a desire to limit dependencies for the framework, but also the 
Tapestry DOM is streamlined for initial creation, and a limited amount of 
subsequent modification. Mo
 st DOM implementations are more sophisticated than needed for Tapestry, with 
greater support for querying (often using XPath) and manipulation.</p><p>Once 
the Document object is created, you don't directly create new DOM objects; 
instead, each DOM object includes methods that create new sub-objects. This 
primarily applies to the Element class, which can be a container of text, 
comments and other elements.</p><h2 id="DOM-Document">Document</h2><p>The <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/dom/Document.html";>Document
 Object</a> represents the an entire document, which is to say, an entire 
response to be sent to the client.</p><p>Documents will have a single root 
element. The newRootElement() method is used to create the root element for the 
document.</p><p>The Document class also has methods for setting and getting the 
DTD, adding comments and text, and finding an element based on a path of 
element names.</p><h2 id="DOM-Element"
 >Element</h2><p>An <a  class="external-link" 
 >href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/dom/Element.html";>Element
 > Object</a> represents an element of the document. Elements may have 
 >attributes, and they may themselves contain other elements, as well as text 
 >and comments.</p><p>The Element class has methods for searching, traversing 
 >and manipulating the DOM after it is built.</p><h1 
 >id="DOM-DOMManipulation/Rewriting">DOM Manipulation/Rewriting</h1><p>A 
 >powerful feature of Tapestry 5 is the ability to manipulate the structure and 
 >ordering of the DOM after it has been rendered. For example, this can be used 
 >to alter the output of a component that may otherwise be outside of your 
 >control.</p><p>DOM manipulation is surprisingly fast, too.</p><p>Methods on 
 >Node (and Element, which is a subclass of Node) allow an existing node to be 
 >moved relative to an Element. Nodes may be moved before or after the Element, 
 >or may be moved inside an Element at the top (the firs
 t child) or the bottom (the last child).</p><p>Element's 
<code>attribute</code> method adds a new attribute name/value pair to the 
Element. If an existing attribute with the specified name already exists, then 
then the new value is ignored. This has implications when different pieces of 
code try to add attributes to an Element ... the first to add an attribute will 
"win". Conversely, the <code>forceAttributes</code> method can be used to 
update or remove an attribute.</p><p>In addition, the children of an Element 
may be removed or a Node (and all of its children) removed 
entirely.</p><p>Finally, an Element may "pop": the Element is removed and 
replaced with its children.</p><h1 
id="DOM-MarkupWriter">MarkupWriter</h1><p>The <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/MarkupWriter.html";>MarkupWriter
 interface</a> allows the structure of the document to be built while 
maintaining a streaming metaphor.</p><h2 id="DOM-element()andend()m
 ethods">element() and end() methods</h2><p>Calls to element() create a new 
element within the tree, and may provide attributes for the new element as 
well. Calls to write(), writeln() and writef() write text nodes within the 
current element. <em>Every call to element() should be matched with a call to 
end()</em>, which is used to move the current node up one level.</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;">  writer.element("img", "src", "icon.png", "width", 20, 
"height", 20, alt, "*");
   writer.end();
-</plain-text-body><p>Note that end() must be called here, even though the 
&lt;img&gt; element is empty (has no body). If the call to end() is omitted, 
then later elements created by calls to element() will be nested 
<em>inside</em> the &lt;img&gt; element, which is not desired.</p><p>Again, 
<strong>every call to element() must be matched with a call to 
end()</strong>:</p><parameter ac:name="">java</parameter><plain-text-body>  
writer.element("select", "name", "choice");
+</pre>
+</div></div><p>Note that end() must be called here, even though the 
&lt;img&gt; element is empty (has no body). If the call to end() is omitted, 
then later elements created by calls to element() will be nested 
<em>inside</em> the &lt;img&gt; element, which is not desired.</p><p>Again, 
<strong>every call to element() must be matched with a call to 
end()</strong>:</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;">  writer.element("select", "name", "choice");
   
   for (String name : optionsNames)
   {
@@ -83,9 +94,12 @@ In Tapestry 4, markup generation was bas
   }
   
   writer.end();
-</plain-text-body><h2 id="DOM-attributes()">attributes()</h2><p>Adds 
additional name/value pairs to the current element.</p><p>When a value is null, 
no attribute is added.</p><p>When a new name conflicts with an existing name, 
the new value is ignored. This gives precedence to the first value specified 
for an attribute over any subsequent value.</p><h2 
id="DOM-write()">write()</h2><p>The write() method writes text inside the 
current element. It scans the provided text for XML control characters ('&lt;', 
'&gt;', and '&amp;') and converts them to their XML entity equivalents ('&lt;', 
'&gt;', and '&amp;'). The result is correct, safe, HTML/XML output even when 
the content (which may come from a template, or from an external source such as 
a database) contains such problematic characters.</p><h2 
id="DOM-writef()">writef()</h2><p>The writef() method formats an number of 
arguments. It uses a java.util.Formatter. It is a convenience for formatting 
that ultimately invokes write().</p><h2 id
 ="DOM-writeRaw()">writeRaw()</h2><p>The writeRaw() method writes unfiltered 
text into the DOM. When the DOM is rendered to markup, the provided string is 
written to the output stream exactly as-is. Care should be taken, as this can 
easily result invalid markup, or even markup that is not well formed.</p><h2 
id="DOM-comment()">comment()</h2><p>Adds an XML comment. The comment delimiters 
will be supplied by Tapestry:</p><parameter 
ac:name="">java</parameter><plain-text-body>  writer.comment("Start of JS Menu 
code");
+</pre>
+</div></div><h2 id="DOM-attributes()">attributes()</h2><p>Adds additional 
name/value pairs to the current element.</p><p>When a value is null, no 
attribute is added.</p><p>When a new name conflicts with an existing name, the 
new value is ignored. This gives precedence to the first value specified for an 
attribute over any subsequent value.</p><h2 id="DOM-write()">write()</h2><p>The 
write() method writes text inside the current element. It scans the provided 
text for XML control characters ('&lt;', '&gt;', and '&amp;') and converts them 
to their XML entity equivalents ('&lt;', '&gt;', and '&amp;'). The result is 
correct, safe, HTML/XML output even when the content (which may come from a 
template, or from an external source such as a database) contains such 
problematic characters.</p><h2 id="DOM-writef()">writef()</h2><p>The writef() 
method formats an number of arguments. It uses a java.util.Formatter. It is a 
convenience for formatting that ultimately invokes write().</p><h2 id="DOM-
 writeRaw()">writeRaw()</h2><p>The writeRaw() method writes unfiltered text 
into the DOM. When the DOM is rendered to markup, the provided string is 
written to the output stream exactly as-is. Care should be taken, as this can 
easily result invalid markup, or even markup that is not well formed.</p><h2 
id="DOM-comment()">comment()</h2><p>Adds an XML comment. The comment delimiters 
will be supplied by Tapestry:</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;">  writer.comment("Start of JS Menu code");
   
-</plain-text-body></div>
+</pre>
+</div></div></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/enum-parameter-recipe.html
==============================================================================
--- websites/production/tapestry/content/enum-parameter-recipe.html (original)
+++ websites/production/tapestry/content/enum-parameter-recipe.html Wed Sep 20 
12:29:16 2017
@@ -27,6 +27,16 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
+    <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
+        <script>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,8 +77,8 @@
       </div>
 
       <div id="content">
-                <div 
id="ConfluenceContent"><plain-text-body>{scrollbar}</plain-text-body>
-<p><parameter ac:name="hidden">true</parameter><rich-text-body><p>Using an 
Enum as a component parameter using coercion</p></rich-text-body></p>
+                <div id="ConfluenceContent">
+<p></p>
 
 <h1 id="EnumParameterRecipe-EnumComponentParameter">Enum Component 
Parameter</h1>
 
@@ -78,7 +88,8 @@
 
 <p>Let's start with the enum type itself:</p>
 
-<parameter ac:name="title">BlankOption.java</parameter><plain-text-body>
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 
1px;"><b>BlankOption.java</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
 public enum BlankOption
 {
     /**
@@ -96,11 +107,13 @@ public enum BlankOption
      */
     AUTO;
 }
-</plain-text-body>
+</pre>
+</div></div>
 
 <p>Next, we define the parameter:</p>
 
-<parameter ac:name="title">Select.java (partial)</parameter><plain-text-body>
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>Select.java 
(partial)</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
 
     /**
      * Controls whether an additional blank option is provided. The blank 
option precedes all other options and is never
@@ -109,13 +122,15 @@ public enum BlankOption
      */
     @Parameter(value = "auto", defaultPrefix = BindingConstants.LITERAL)
     private BlankOption blankOption;
-</plain-text-body>
+</pre>
+</div></div>
 
 <p>Note the use of literal as the default prefix; this allows us to use the 
name of the option in our template, e.g. <code>&lt;t:select blankoption="never" 
.../&gt;</code>.  Without the default prefix setting, "never" would be 
interpreted as a property expression (and you'd see an error when you loaded 
the page).</p>
 
 <p>The final piece of the puzzle is to inform Tapestry how to convert from a 
string, such as "never", to a BlankOption value.</p>
 
-<parameter ac:name="title">TapestryModule.java 
(partial)</parameter><plain-text-body>
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>TapestryModule.java 
(partial)</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
     public static void 
contributeTypeCoercer(Configuration&lt;CoercionTuple&gt; configuration)
     {
        . . .
@@ -129,7 +144,8 @@ public enum BlankOption
     {
         configuration.add(CoercionTuple.create(String.class, enumType, 
StringToEnumCoercion.create(enumType)));
     }
-</plain-text-body>
+</pre>
+</div></div>
 
 <p>The TypeCoercer service is ultimately responsible for converting the string 
to a BlankOption, but we have to tell it how, by contributing an appropriate 
CoercionTuple. The CoercionTuple identifies the source and target types (String 
and BlankOption), and an object to perform the coercion (an instance of 
StringToEnumCoercion, via the <code>create()</code> static method).</p></div>
       </div>


Reply via email to