Modified: websites/production/tapestry/content/confluence-site-setup.html ============================================================================== --- websites/production/tapestry/content/confluence-site-setup.html (original) +++ websites/production/tapestry/content/confluence-site-setup.html Sat Feb 3 18:21:36 2018 @@ -36,13 +36,26 @@ <div class="wrapper bs"> - <div id="navigation"><div class="nav"><ul class="alternate"><li><a href="index.html">Home</a></li><li><a href="getting-started.html">Getting Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a href="download.html">Download</a></li><li><a href="about.html">About</a></li><li><a class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a href="community.html">Community</a></li><li><a class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a class="external-link" href="http://www.apache.org/">Apache</a></li><li><a class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div></div> + <div id="navigation"><div class="nav"><ul class="alternate"><li><a href="index.html">Home</a></li><li><a href="getting-started.html">Getting Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a href="download.html">Download</a></li><li><a href="about.html">About</a></li><li><a class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a href="community.html">Community</a></li><li><a class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a class="external-link" href="http://www.apache.org/">Apache</a></li><li><a class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div> + +</div> <div id="top"> - <div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis & blogs:</span><form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html"> - <input type="text" name="q"> - <input type="submit" value="Search"> -</form></div><div class="emblem" style="float:left"><p><a href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Confluence Site Setup</h1></div></div> + <div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis & blogs:</span> +<form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html"> + <input type="text" name="q"> + <input type="submit" value="Search"> +</form> + +</div> + + +<div class="emblem" style="float:left"><p><a href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div> + + +<div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Confluence Site Setup</h1></div> + +</div> <div class="clearer"></div> </div> @@ -54,43 +67,76 @@ </div> <div id="content"> - <div id="ConfluenceContent"><p>This document describes our web site setup: what is where and how it works.</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><h1 id="ConfluenceSiteSetup-Overview">Overview</h1><p>Most of the web site and documentation (with the notable exception of the Javadoc API pages) are kept in Confluence.</p><p>Since the Confluence instance at <a class="external-link" href="https://cwiki.apache.org/confluence/">https://cwiki.apache.org/confluence/</a> isn't capable of handling a lot of incoming requests, all wiki spaces are statically exported. The SiteExporter program is responsible for that. Once a page in Confluence changes, that page gets re-exported automatically.</p><h2 id="ConfluenceSiteSetup-HowSiteExporterworks">How SiteExporter works</h2><p><em>For more details see the <a class="external-link" href="https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk/README">SiteExporter README</a>.</em></p><p>SiteExporter is a command-line Java program that is run hourly (currently at 19 minutes after the hour) from Apache's BuildBot. It makes a web service call to Confluence (to its R SS feed, actually) to get a list of pages that have changed since the last run, and the HTML-formatted export of those pages. For each, it post-processes the file (described below). Finally, SiteExporter commits all changed HTML files into Tapestry's part of the Apache Subversion repository, which (nearly instantly) makes it available to the public at <a class="external-link" href="http://tapestry.apache.org">http://tapestry.apache.org</a>, and commit emails are sent to Tapestry's "commits" mailing list.</p><p>Attachments (to Confluence pages) are exported in roughly the same way.</p><p>The time between saving a change in Confluence and seeing the result on the public site is at most 1 hour, depending on when you do it. If you save a change at 18 minutes after the hour you'll see the change in about a minute. If you publish it at 20 minutes after the hour then you'll have to wait almost an hour.</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1" ro wspan="1" class="confluenceTd"><p>HTML files in SVN</p></td><td colspan="1" rowspan="1" class="confluenceTd"><a class="external-link" href="https://svn.apache.org/repos/infra/websites/production/tapestry">https://svn.apache.org/repos/infra/websites/production/tapestry</a></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>Cache File</p></td><td colspan="1" rowspan="1" class="confluenceTd"><a class="external-link" href="https://svn.apache.org/repos/infra/websites/production/tapestry/content/cache/main.pageCache">https://svn.apache.org/repos/infra/websites/production/tapestry/content/cache/main.pageCache</a></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>SiteExporter source</p></td><td colspan="1" rowspan="1" class="confluenceTd"><a class="external-link" href="https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk">https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk</a></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p >Velocity template</p></td><td colspan="1" rowspan="1" class="confluenceTd"><a > class="external-link" >href="https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk/template/template.vm">https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk/template/template.vm</a></td></tr></tbody></table></div><h3 > id="ConfluenceSiteSetup-Post-processingHTMLPages">Post-processing HTML >Pages</h3><p>HTML pages exported from Confluence are post-processed in >several ways before being committed to SVN. Here are just a few of the things >going on:</p><ul><li>Tagsoup is used to clean up the HTML.</li><li>The >breadcrumb links are updated.</li><li>Empty paragraph (<p>) tags are >removed from the top of the page.</li><li>{code} macro output (code examples) >are detected, and SyntaxHighlighter JavaScript links are added to the page >when needed.</li><li>{include} tags (when one Confluence page includes >another) are detected, causing the <em>including</em> page to be regenerated >autoamtically.</ li><li>{children} tags are also detected and handled</li></ul><h2 id="ConfluenceSiteSetup-ManualIntervention">Manual Intervention</h2><p>You can cause the <em>whole site</em> to be republished by deleting the main.pageCache file (above) in the subversion repo. This is usually only needed after changing the template.</p><h2 id="ConfluenceSiteSetup-ChangingSiteExporteritself">Changing SiteExporter itself</h2><p>Currently the SiteExporter source code is an unmodified copy of a program of the same name written by Dan Kulp for the Apache CXF project and also used by Camel, Geronimo, and Struts (and possibly others). It can be customized, but proceed with caution, because any customizations will make it harder to pull in future changes from the original CXF SiteExporter code. The CXF SiteExporter is likely to change as Confluence versions change.</p><p>To pick up changes to the original CXF SiteExporter code, just compare <a class="external-link" href="https://svn.apache.org/repos/asf/ta pestry/tapestry-site/trunk/src/main/java/org/apache/cxf/cwiki">the Tapestry source code</a> with <a class="external-link" href="http://svn.apache.org/repos/asf/cxf/web/src/main/java/org/apache/cxf/cwiki/">the CXF source code</a>.</p><hr><h1 id="ConfluenceSiteSetup-WikiFormattingGuidelines">Wiki Formatting Guidelines</h1><ul><li>Precede annotation names with '@'. If the annotation name is hyperlinked, put the '@' character <em>outside</em> of the link: @[AnnotationType|http://...AnnotationType.html]</li><li>The first reference to a type on a page should be a link to <a class="external-link" href="http://tapestry.apache.org/current/apidocs/">http://tapestry.apache.org/current/apidocs/</a>... (or the component reference)</li><li>Treat the page title as if it were an h0. element, and put top level sections within the page as h1.</li><li>Page names as headings should have All Words Captialized.</li><li>For other headings, only the first word of multi-word headings should be capitalized , e.g. "h2. Naming conventions" (following Wikipedia)</li><li>Use <code>code</code> font for method and property names: <code>myProperty</code>, <code>someMethod()</code>.</li><li>Use the default font for Class names (qualified or not).</li><li>Use the default font for path names.</li><li>Use {code} for listings, not {noformat}.</li><li>Use {noformat} for console output.</li><li>Images and diagrams should be small-sized thumbnails, centered, with no border.</li><li>Use the <a href="since-and-deprecated-user-macros.html">Since and Deprecated</a> macros to mark new or deprecated features.</li><li><em>Proposed: Each page should include explicit links to its child pages. Don't rely on the "Child Pages" links at the bottom, which don't carry over to the exported site.</em></li><li><em>Proposed: In pages other than the User Guide pages, subsections that briefly discuss topics that are more fully covered in the User Guide should lead with a "Main Article: [Foo]" line, where Foo is the nam e of the page in the User Guide. Example: the "Template Localization" section of <a href="component-templates.html">Component Templates</a></em></li><li><em>Proposed: User Guide pages should generally start with a right-floated "Related Articles" box that provides links to related content in the FAQ, Cookbook, Cheat Sheets, etc. <a href="component-classes.html">Example</a></em></li><li><em>Proposed: The lead paragraph should generally lead with the title word or phrase in bold (following Wikipedia)</em></li></ul><h1 id="ConfluenceSiteSetup-Websitestructure">Website structure</h1><p>The <a href="index.html">Index</a> page includes the <a href="banner.html">Banner</a> and <a href="key-features.html">Key Features</a> pages as well as the blog posts. Most other pages are just plain pages and may or may not include other parts. In addition the <a href="navigation.html">Navigation</a>, <a href="small-banner.html">Small Banner</a> and <a href="footer.html">Footer</a> pages exist.</ p><p>Our SiteExporter template (described above) glues everything together. It adds the contents of the <a href="navigation.html">Navigation</a> and <a href="footer.html">Footer</a> pages in the appropriate places and on all pages except the <a href="index.html">Index</a> page. It also adds the contents of the <a href="small-banner.html">Small Banner</a> page as well as the breadcrumbs navigation.</p><div class="confluence-information-macro confluence-information-macro-warning"><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>HLS: I've noticed that pages with footnotes that are combined with the {include} macro do not render correctly ... the footnote numbers and anchors reset back to 1 for each included page. Perhaps there's a way to fix that with the template?</p></div></div><h1 id="ConfluenceSiteSetup-Updatingthetemplate">Updating the template</h1><p>You must be a Tapestry commi tter or otherwise have write access to the subversion repository (see link above).</p><p>To edit the template:</p><ol><li>check out the SiteExporter source project (see link above)</li><li>find and edit the template.vm file</li><li>commit your changes</li></ol></div> + <div id="ConfluenceContent"><p>This document describes our web site setup: what is where and how it works.</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> + + +<h1 id="ConfluenceSiteSetup-Overview">Overview</h1><p>Most of the web site and documentation (with the notable exception of the Javadoc API pages) are kept in Confluence.</p><p>Since the Confluence instance at <a class="external-link" href="https://cwiki.apache.org/confluence/">https://cwiki.apache.org/confluence/</a> isn't capable of handling a lot of incoming requests, all wiki spaces are statically exported. The SiteExporter program is responsible for that. Once a page in Confluence changes, that page gets re-exported automatically.</p><h2 id="ConfluenceSiteSetup-HowSiteExporterworks">How SiteExporter works</h2><p><em>For more details see the <a class="external-link" href="https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk/README">SiteExporter README</a>.</em></p><p>SiteExporter is a command-line Java program that is run hourly (currently at 19 minutes after the hour) from Apache's BuildBot. It makes a web service call to Confluence (to its RSS feed, actually) to get a list of pages that have changed since the last run, and the HTML-formatted export of those pages. For each, it post-processes the file (described below). Finally, SiteExporter commits all changed HTML files into Tapestry's part of the Apache Subversion repository, which (nearly instantly) makes it available to the public at <a class="external-link" href="http://tapestry.apache.org">http://tapestry.apache.org</a>, and commit emails are sent to Tapestry's "commits" mailing list.</p><p>Attachments (to Confluence pages) are exported in roughly the same way.</p><p>The time between saving a change in Confluence and seeing the result on the public site is at most 1 hour, depending on when you do it. If you save a change at 18 minutes after the hour you'll see the change in about a minute. If you publish it at 20 minutes after the hour then you'll have to wait almost an hour.</p><div class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1" class="confluen ceTd"><p>HTML files in SVN</p></td><td colspan="1" rowspan="1" class="confluenceTd"><a class="external-link" href="https://svn.apache.org/repos/infra/websites/production/tapestry">https://svn.apache.org/repos/infra/websites/production/tapestry</a></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>Cache File</p></td><td colspan="1" rowspan="1" class="confluenceTd"><a class="external-link" href="https://svn.apache.org/repos/infra/websites/production/tapestry/content/cache/main.pageCache">https://svn.apache.org/repos/infra/websites/production/tapestry/content/cache/main.pageCache</a></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>SiteExporter source</p></td><td colspan="1" rowspan="1" class="confluenceTd"><a class="external-link" href="https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk">https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk</a></td></tr><tr><td colspan="1" rowspan="1" class="confluenceTd"><p>Velocity template</p></t d><td colspan="1" rowspan="1" class="confluenceTd"><a class="external-link" href="https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk/template/template.vm">https://svn.apache.org/repos/asf/tapestry/tapestry-site/trunk/template/template.vm</a></td></tr></tbody></table></div><h3 id="ConfluenceSiteSetup-Post-processingHTMLPages">Post-processing HTML Pages</h3><p>HTML pages exported from Confluence are post-processed in several ways before being committed to SVN. Here are just a few of the things going on:</p><ul><li>Tagsoup is used to clean up the HTML.</li><li>The breadcrumb links are updated.</li><li>Empty paragraph (<p>) tags are removed from the top of the page.</li><li>{code} macro output (code examples) are detected, and SyntaxHighlighter JavaScript links are added to the page when needed.</li><li>{include} tags (when one Confluence page includes another) are detected, causing the <em>including</em> page to be regenerated autoamtically.</li><li>{children} tags ar e also detected and handled</li></ul><h2 id="ConfluenceSiteSetup-ManualIntervention">Manual Intervention</h2><p>You can cause the <em>whole site</em> to be republished by deleting the main.pageCache file (above) in the subversion repo. This is usually only needed after changing the template.</p><h2 id="ConfluenceSiteSetup-ChangingSiteExporteritself">Changing SiteExporter itself</h2><p>Currently the SiteExporter source code is an unmodified copy of a program of the same name written by Dan Kulp for the Apache CXF project and also used by Camel, Geronimo, and Struts (and possibly others). It can be customized, but proceed with caution, because any customizations will make it harder to pull in future changes from the original CXF SiteExporter code. The CXF SiteExporter is likely to change as Confluence versions change.</p><p>To pick up changes to the original CXF SiteExporter code, just compare <a class="external-link" href="https://svn.apache.org/repos/asf/tapestry/tapestry-site/trun k/src/main/java/org/apache/cxf/cwiki">the Tapestry source code</a> with <a class="external-link" href="http://svn.apache.org/repos/asf/cxf/web/src/main/java/org/apache/cxf/cwiki/">the CXF source code</a>.</p><hr><h1 id="ConfluenceSiteSetup-WikiFormattingGuidelines">Wiki Formatting Guidelines</h1><ul><li>Precede annotation names with '@'. If the annotation name is hyperlinked, put the '@' character <em>outside</em> of the link: @[AnnotationType|http://...AnnotationType.html]</li><li>The first reference to a type on a page should be a link to <a class="external-link" href="http://tapestry.apache.org/current/apidocs/">http://tapestry.apache.org/current/apidocs/</a>... (or the component reference)</li><li>Treat the page title as if it were an h0. element, and put top level sections within the page as h1.</li><li>Page names as headings should have All Words Captialized.</li><li>For other headings, only the first word of multi-word headings should be capitalized, e.g. "h2. Naming conven tions" (following Wikipedia)</li><li>Use <code>code</code> font for method and property names: <code>myProperty</code>, <code>someMethod()</code>.</li><li>Use the default font for Class names (qualified or not).</li><li>Use the default font for path names.</li><li>Use {code} for listings, not {noformat}.</li><li>Use {noformat} for console output.</li><li>Images and diagrams should be small-sized thumbnails, centered, with no border.</li><li>Use the <a href="confluence-site-setup.html">Since and Deprecated</a> macros to mark new or deprecated features.</li><li><em>Proposed: Each page should include explicit links to its child pages. Don't rely on the "Child Pages" links at the bottom, which don't carry over to the exported site.</em></li><li><em>Proposed: In pages other than the User Guide pages, subsections that briefly discuss topics that are more fully covered in the User Guide should lead with a "Main Article: [Foo]" line, where Foo is the name of the page in the User Guide. Exa mple: the "Template Localization" section of <a href="confluence-site-setup.html">Confluence Site Setup</a></em></li><li><em>Proposed: User Guide pages should generally start with a right-floated "Related Articles" box that provides links to related content in the FAQ, Cookbook, Cheat Sheets, etc. <a href="confluence-site-setup.html">Example</a></em></li><li><em>Proposed: The lead paragraph should generally lead with the title word or phrase in bold (following Wikipedia)</em></li></ul><h1 id="ConfluenceSiteSetup-Websitestructure">Website structure</h1><p>The <a href="confluence-site-setup.html">Confluence Site Setup</a> page includes the <a href="confluence-site-setup.html">Confluence Site Setup</a> and <a href="confluence-site-setup.html">Confluence Site Setup</a> pages as well as the blog posts. Most other pages are just plain pages and may or may not include other parts. In addition the <a href="confluence-site-setup.html">Confluence Site Setup</a>, <a href="confluence-sit e-setup.html">Confluence Site Setup</a> and <a href="confluence-site-setup.html">Confluence Site Setup</a> pages exist.</p><p>Our SiteExporter template (described above) glues everything together. It adds the contents of the <a href="confluence-site-setup.html">Confluence Site Setup</a> and <a href="confluence-site-setup.html">Confluence Site Setup</a> pages in the appropriate places and on all pages except the <a href="confluence-site-setup.html">Confluence Site Setup</a> page. It also adds the contents of the <a href="confluence-site-setup.html">Confluence Site Setup</a> page as well as the breadcrumbs navigation.</p><div class="confluence-information-macro confluence-information-macro-warning"><span class="aui-icon aui-icon-small aui-iconfont-error confluence-information-macro-icon"></span><div class="confluence-information-macro-body"><p>HLS: I've noticed that pages with footnotes that are combined with the {include} macro do not render correctly ... the footnote numbers an d anchors reset back to 1 for each included page. Perhaps there's a way to fix that with the template?</p></div></div><h1 id="ConfluenceSiteSetup-Updatingthetemplate">Updating the template</h1><p>You must be a Tapestry committer or otherwise have write access to the subversion repository (see link above).</p><p>To edit the template:</p><ol><li>check out the SiteExporter source project (see link above)</li><li>find and edit the template.vm file</li><li>commit your changes</li></ol></div> </div> <div class="clearer"></div>
Modified: websites/production/tapestry/content/default-parameter.html ============================================================================== --- websites/production/tapestry/content/default-parameter.html (original) +++ websites/production/tapestry/content/default-parameter.html Sat Feb 3 18:21:36 2018 @@ -45,13 +45,26 @@ <div class="wrapper bs"> - <div id="navigation"><div class="nav"><ul class="alternate"><li><a href="index.html">Home</a></li><li><a href="getting-started.html">Getting Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a href="download.html">Download</a></li><li><a href="about.html">About</a></li><li><a class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a href="community.html">Community</a></li><li><a class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a class="external-link" href="http://www.apache.org/">Apache</a></li><li><a class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div></div> + <div id="navigation"><div class="nav"><ul class="alternate"><li><a href="index.html">Home</a></li><li><a href="getting-started.html">Getting Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a href="download.html">Download</a></li><li><a href="about.html">About</a></li><li><a class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a href="community.html">Community</a></li><li><a class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a class="external-link" href="http://www.apache.org/">Apache</a></li><li><a class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div> + +</div> <div id="top"> - <div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis & blogs:</span><form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html"> - <input type="text" name="q"> - <input type="submit" value="Search"> -</form></div><div class="emblem" style="float:left"><p><a href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Default Parameter</h1></div></div> + <div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis & blogs:</span> +<form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html"> + <input type="text" name="q"> + <input type="submit" value="Search"> +</form> + +</div> + + +<div class="emblem" style="float:left"><p><a href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div> + + +<div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">Default Parameter</h1></div> + +</div> <div class="clearer"></div> </div> @@ -63,31 +76,58 @@ </div> <div id="content"> - <div id="ConfluenceContent"><p> </p><p>Many of the components provided with Tapestry share a common behavior: if the component's id matches a property of the container, then some parameter of the component (usually value) defaults to that property.</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="enum-parameter-recipe.html">Enum Parameter Recipe</a> - </div> </li><li> - <div> - <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> - </div> - <div class="details"> - <a href="supporting-informal-parameters.html">Supporting Informal Parameters</a> - </div> </li><li> - <div> - <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> - </div> - <div class="details"> - <a href="default-parameter.html">Default Parameter</a> - </div> </li><li> - <div> - <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> - </div> - <div class="details"> - <a href="component-parameters.html">Component Parameters</a> - </div> </li></ul></div><p>This is desirable, in terms of not having to specify the component's id and then specify the same value as some other parameter.</p><p>Let's say you have created a component, <code>RichTextEditor</code>, which operates like a normal TextArea component, but provides a JavaScript rich text editor. You might start with something like:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> + <div id="ConfluenceContent"><p> </p><p>Many of the components provided with Tapestry share a common behavior: if the component's id matches a property of the container, then some parameter of the component (usually value) defaults to that property.</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="enum-parameter-recipe.html">Enum Parameter Recipe</a> + + + </div> + </li><li> + <div> + <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> </div> + + <div class="details"> + <a href="supporting-informal-parameters.html">Supporting Informal Parameters</a> + + + </div> + </li><li> + <div> + <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> </div> + + <div class="details"> + <a href="default-parameter.html">Default Parameter</a> + + + </div> + </li><li> + <div> + <span class="icon aui-icon aui-icon-small aui-iconfont-page-default" title="Page">Page:</span> </div> + + <div class="details"> + <a href="component-parameters.html">Component Parameters</a> + + + </div> + </li></ul> +</div> + + +<p>This is desirable, in terms of not having to specify the component's id and then specify the same value as some other parameter.</p><p>Let's say you have created a component, <code>RichTextEditor</code>, which operates like a normal TextArea component, but provides a JavaScript rich text editor. You might start with something like:</p><div class="code panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl"> <pre class="brush: java; gutter: false; theme: Default" style="font-size:12px;">public class RichTextEditor implements Field { @Property Modified: websites/production/tapestry/content/developer-bible.html ============================================================================== --- websites/production/tapestry/content/developer-bible.html (original) +++ websites/production/tapestry/content/developer-bible.html Sat Feb 3 18:21:36 2018 @@ -44,13 +44,26 @@ <div class="wrapper bs"> - <div id="navigation"><div class="nav"><ul class="alternate"><li><a href="index.html">Home</a></li><li><a href="getting-started.html">Getting Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a href="download.html">Download</a></li><li><a href="about.html">About</a></li><li><a class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a href="community.html">Community</a></li><li><a class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a class="external-link" href="http://www.apache.org/">Apache</a></li><li><a class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div></div> + <div id="navigation"><div class="nav"><ul class="alternate"><li><a href="index.html">Home</a></li><li><a href="getting-started.html">Getting Started</a></li><li><a href="documentation.html">Documentation</a></li><li><a href="download.html">Download</a></li><li><a href="about.html">About</a></li><li><a class="external-link" href="http://www.apache.org/licenses/LICENSE-2.0">License</a></li><li><a href="community.html">Community</a></li><li><a class="external-link" href="http://www.apache.org/security/">Security</a></li><li><a class="external-link" href="http://www.apache.org/">Apache</a></li><li><a class="external-link" href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li><li><a class="external-link" href="http://www.apache.org/foundation/thanks.html">Thanks</a></li></ul></div> + +</div> <div id="top"> - <div id="smallbanner"><div class="searchbox" style="float:right;margin: .3em 1em .1em 1em"><span style="color: #999; font-size: 90%">Tapestry docs, issues, wikis & blogs:</span><form enctype="application/x-www-form-urlencoded" method="get" action="http://tapestry.apache.org/search.html"> - <input type="text" name="q"> - <input type="submit" value="Search"> -</form></div><div class="emblem" style="float:left"><p><a href="index.html"><span class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image confluence-external-resource" src="http://tapestry.apache.org/images/tapestry_small.png" data-image-src="http://tapestry.apache.org/images/tapestry_small.png"></span></a></p></div><div class="title" style="float:left; margin: 0 0 0 3em"><h1 id="SmallBanner-PageTitle">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 & 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> @@ -62,43 +75,76 @@ </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 & 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 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 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&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&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 – 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 – 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"> + <div id="ConfluenceContent"><p>IDE choices, coding style and formatting, commit practices, naming conventions and other issues relevant to Tapestry committers & 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/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 me ssage. 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 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 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&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 cla ss="external-link" href="https://issues.apache.org/jira/secure/IssueNavigator.jspa?mode=hide&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 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 – 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 – 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 hig h 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 components.</p><h2 id="DeveloperBi ble-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 interfa ce 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) @@ -120,7 +166,7 @@ }; } </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&Formatting">Code Style & 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><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&Formatting">Code Style & 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/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">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/enum-parameter-recipe.html ============================================================================== --- websites/production/tapestry/content/enum-parameter-recipe.html (original) +++ websites/production/tapestry/content/enum-parameter-recipe.html Sat Feb 3 18:21:36 2018 @@ -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,19 +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> - -<h1 id="EnumParameterRecipe-EnumComponentParameter">Enum Component Parameter</h1> - -<p>It's not uncommon to create a component that has a bit of complex behavior that you want to be able to easily control, and an enumerated type (a Java enum) seems like the right approach. </p> - -<p>Our example comes from Tapestry's Select component, which has a blankOption parameter that has an enum type.</p> - -<p>Let's start with the enum type itself:</p> - -<parameter ac:name="title">BlankOption.java</parameter><plain-text-body> -public enum BlankOption + <div id="ConfluenceContent"><h1 id="EnumParameterRecipe-EnumComponentParameter">Enum Component Parameter</h1><p>It's not uncommon to create a component that has a bit of complex behavior that you want to be able to easily control, and an enumerated type (a Java enum) seems like the right approach.</p><p>Our example comes from Tapestry's Select component, which has a blankOption parameter that has an enum type.</p><p>Let's start with the enum type itself:</p><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 { /** * Always include the blank option, even if the underlying property is required. @@ -96,27 +95,18 @@ public enum BlankOption */ AUTO; } -</plain-text-body> - -<p>Next, we define the parameter:</p> - -<parameter ac:name="title">Select.java (partial)</parameter><plain-text-body> - - /** +</pre> +</div></div><p>Next, we define the parameter:</p><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 * selected. The value for the blank option is always the empty string, the label may be the blank string; the * label is from the blankLabel parameter (and is often also the empty string). */ @Parameter(value = "auto", defaultPrefix = BindingConstants.LITERAL) private BlankOption blankOption; -</plain-text-body> - -<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><t:select blankoption="never" .../></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> - public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration) +</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><t:select blankoption="never" .../></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><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<CoercionTuple> configuration) { . . . @@ -129,9 +119,8 @@ public enum BlankOption { configuration.add(CoercionTuple.create(String.class, enumType, StringToEnumCoercion.create(enumType))); } -</plain-text-body> - -<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> +</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> <div class="clearer"></div>
