Modified: websites/production/tapestry/content/limitations.html
==============================================================================
--- websites/production/tapestry/content/limitations.html (original)
+++ websites/production/tapestry/content/limitations.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,7 +77,8 @@
       </div>
 
       <div id="content">
-                <div 
id="ConfluenceContent"><plain-text-body>{scrollbar}</plain-text-body><h2 
id="Limitations-Limitations">Limitations</h2><h3 
id="Limitations-HowdoIaddnewcomponentstoanexistingpagedynamically?">How do I 
add new components to an existing page dynamically?</h3><p>The short answer 
here is: <strong>you don't</strong>. The long answer here is <strong>you don't 
have to, to get the behavior you desire</strong>.</p><p>One of Tapestry basic 
values is high scalability: this is expressed in a number of ways, reflecting 
scalability concerns within a single server, and within a cluster of 
servers.</p><p>Although you code Tapestry pages and components as if they were 
ordinary POJOs (<span style="line-height: 1.4285715;">Plain Old Java Objects -- 
Tapestry does not require you to extend any base classes or implement any 
special interfaces)</span><span style="line-height: 1.4285715;">, as deployed 
by Tapestry they are closer to a traditional servlet: a single instance of each 
page s
 ervices requests from multiple threads. Behind the scenes, Tapestry transforms 
you code, rewriting it on the fly.</span></p><p>What this means is that 
<em>any</em> incoming request must be handled by a <em>single page 
instance</em>. Therefore, Tapestry enforces the concept of <strong>static 
structure, dynamic behavior</strong>.</p><p>Tapestry provides quite a number of 
ways to vary what content is rendered, well beyond simple conditionals and 
loops. It is possible to "drag in" components from other pages when rendering a 
page (other FAQs will expand on this concept). The point is, that although a 
Tapestry page's structure is very rigid, the order in which the components of 
the page render does not have to be top to bottom.</p><h3 
id="Limitations-Whydoesn'tmyserviceimplementationreloadwhenIchangeit?">Why 
doesn't my service implementation reload when I change it?</h3><p>Main article: 
<a  href="service-implementation-reloading.html">Service Implementation 
Reloading</a></p><p>Live servi
 ce reloading has some limitations:</p><ul><li>The service must define a 
service interface.</li><li>The service implementation must be on the file 
system (not inside a JAR).</li><li>The implementation must be instantiated by 
Tapestry, not inside code (even code inside a module class).</li><li>The 
service must use the default <a  
href="defining-tapestry-ioc-services.html">scope</a> (reloading of perthread 
scopes is not supported).</li></ul><p>Consider the following example 
module:</p><parameter ac:name="controls">true</parameter><parameter 
ac:name="linenumbers">true</parameter><plain-text-body>public static void 
bind(ServiceBinder binder)
+                <div id="ConfluenceContent"><h2 
id="Limitations-Limitations">Limitations</h2><h3 
id="Limitations-HowdoIaddnewcomponentstoanexistingpagedynamically?">How do I 
add new components to an existing page dynamically?</h3><p>The short answer 
here is: <strong>you don't</strong>. The long answer here is <strong>you don't 
have to, to get the behavior you desire</strong>.</p><p>One of Tapestry basic 
values is high scalability: this is expressed in a number of ways, reflecting 
scalability concerns within a single server, and within a cluster of 
servers.</p><p>Although you code Tapestry pages and components as if they were 
ordinary POJOs (<span style="line-height: 1.4285715;">Plain Old Java Objects -- 
Tapestry does not require you to extend any base classes or implement any 
special interfaces)</span><span style="line-height: 1.4285715;">, as deployed 
by Tapestry they are closer to a traditional servlet: a single instance of each 
page services requests from multiple threads. Behind
  the scenes, Tapestry transforms you code, rewriting it on the 
fly.</span></p><p>What this means is that <em>any</em> incoming request must be 
handled by a <em>single page instance</em>. Therefore, Tapestry enforces the 
concept of <strong>static structure, dynamic behavior</strong>.</p><p>Tapestry 
provides quite a number of ways to vary what content is rendered, well beyond 
simple conditionals and loops. It is possible to "drag in" components from 
other pages when rendering a page (other FAQs will expand on this concept). The 
point is, that although a Tapestry page's structure is very rigid, the order in 
which the components of the page render does not have to be top to 
bottom.</p><h3 
id="Limitations-Whydoesn'tmyserviceimplementationreloadwhenIchangeit?">Why 
doesn't my service implementation reload when I change it?</h3><p>Main article: 
<a  href="service-implementation-reloading.html">Service Implementation 
Reloading</a></p><p>Live service reloading has some limitations:</p><ul><li>
 The service must define a service interface.</li><li>The service 
implementation must be on the file system (not inside a JAR).</li><li>The 
implementation must be instantiated by Tapestry, not inside code (even code 
inside a module class).</li><li>The service must use the default <a  
href="defining-tapestry-ioc-services.html">scope</a> (reloading of perthread 
scopes is not supported).</li></ul><p>Consider the following example 
module:</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: true; theme: Default" 
style="font-size:12px;">public static void bind(ServiceBinder binder)
 {
   binder.bind(ArchiveService.class, ArchiveServiceImpl.class);
 }
@@ -80,7 +91,8 @@ public static JobQueue buildJobQueue(Mes
  
   return service;
 }
-</plain-text-body><p>ArchiveService is reloadable, because Tapestry 
instantiates <code>ArchiveServiceImpl</code> itself. On the other hand, 
Tapestry invokes <code>buildJobQueue()</code> and it is your code inside the 
method that instantiates <code>JobQueueImpl</code>, so the JobQueue service 
will not be reloadable.</p><p>Finally, only classes whose class files are 
stored directly on the file system, and not packaged inside JARs, are ever 
reloadable ... generally, only the services of the application being built (and 
not services from libraries) will be stored on the file system. This reflects 
the intent of reloading: as an agile development tool, but not something to be 
used in deployment.</p><h3 
id="Limitations-HowdoIrunmultipleTapestryapplicationsinthesamewebapplication?">How
 do I run multiple Tapestry applications in the same web 
application?</h3><p>Running multiple Tapestry 5 applications is not supported; 
there's only one place to identify the application root package, so even 
 configuring multiple filters into multiple folders will not 
work.</p><p>Support for multiple Tapestry applications in the same web 
application was a specific non-goal in Tapestry 5 (it needlessly complicated 
Tapestry 4). Given how loosely connected Tapestry 5 pages are from each other, 
there doesn't seem to be an advantage to doing so ... and certainly, in terms 
of memory utilization, there is a significant down side, were it even 
possible.</p><p>You&#160;<em>can</em>&#160;<span style="color: rgb(0,0,0);">run 
a Tapestry 4 app and a Tapestry 5 app side-by-side (the package names are 
different, for just this reason), but they know nothing of each other, and 
can't interact directly. This is just like the way you could have a single WAR 
with multiple servlets; the different applications can only communicate via 
URLs, or shared state in the 
HttpSession.</span></p><plain-text-body>{scrollbar}</plain-text-body><p>&#160;</p><p>&#160;</p><p>&#160;</p></div>
+</pre>
+</div></div><p>ArchiveService is reloadable, because Tapestry instantiates 
<code>ArchiveServiceImpl</code> itself. On the other hand, Tapestry invokes 
<code>buildJobQueue()</code> and it is your code inside the method that 
instantiates <code>JobQueueImpl</code>, so the JobQueue service will not be 
reloadable.</p><p>Finally, only classes whose class files are stored directly 
on the file system, and not packaged inside JARs, are ever reloadable ... 
generally, only the services of the application being built (and not services 
from libraries) will be stored on the file system. This reflects the intent of 
reloading: as an agile development tool, but not something to be used in 
deployment.</p><h3 
id="Limitations-HowdoIrunmultipleTapestryapplicationsinthesamewebapplication?">How
 do I run multiple Tapestry applications in the same web 
application?</h3><p>Running multiple Tapestry 5 applications is not supported; 
there's only one place to identify the application root package, so even config
 uring multiple filters into multiple folders will not work.</p><p>Support for 
multiple Tapestry applications in the same web application was a specific 
non-goal in Tapestry 5 (it needlessly complicated Tapestry 4). Given how 
loosely connected Tapestry 5 pages are from each other, there doesn't seem to 
be an advantage to doing so ... and certainly, in terms of memory utilization, 
there is a significant down side, were it even 
possible.</p><p>You&#160;<em>can</em>&#160;<span style="color: rgb(0,0,0);">run 
a Tapestry 4 app and a Tapestry 5 app side-by-side (the package names are 
different, for just this reason), but they know nothing of each other, and 
can't interact directly. This is just like the way you could have a single WAR 
with multiple servlets; the different applications can only communicate via 
URLs, or shared state in the 
HttpSession.</span></p><p>&#160;</p><p>&#160;</p><p>&#160;</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/link-components-faq.html
==============================================================================
--- websites/production/tapestry/content/link-components-faq.html (original)
+++ websites/production/tapestry/content/link-components-faq.html Wed Sep 20 
12:29:16 2017
@@ -27,6 +27,16 @@
       </title>
   <link type="text/css" rel="stylesheet" href="/resources/space.css" />
 
+          <link href='/resources/highlighter/styles/shCoreCXF.css' 
rel='stylesheet' type='text/css' />
+    <link href='/resources/highlighter/styles/shThemeCXF.css' rel='stylesheet' 
type='text/css' />
+    <script src='/resources/highlighter/scripts/shCore.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushJava.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushXml.js' 
type='text/javascript'></script>
+          <script src='/resources/highlighter/scripts/shBrushPlain.js' 
type='text/javascript'></script>
+        <script>
+      SyntaxHighlighter.defaults['toolbar'] = false;
+      SyntaxHighlighter.all();
+    </script>
   
   <link href="/styles/style.css" rel="stylesheet" type="text/css"/>
 
@@ -67,8 +77,11 @@
       </div>
 
       <div id="content">
-                <div 
id="ConfluenceContent"><plain-text-body>{scrollbar}</plain-text-body><h2 
id="LinkComponentsFAQ-LinkComponents">Link Components</h2><h3 
id="LinkComponentsFAQ-HowdoIaddqueryparameterstoaPageLinkorActionLink?">How do 
I add query parameters to a PageLink or ActionLink?</h3><p>These components do 
not have parameters to allow you to specify query parameters for the link; they 
both allow you to specify a <em>context</em> (one or more values to encode into 
the request path).</p><p>However, you can accomplish the same thing with a 
little code and markup. For example, to create a link to another page and pass 
a query parameter, you can replace your PageLink component with a standard 
<code>&lt;a&gt;</code> tag:</p><parameter 
ac:name="controls">true</parameter><parameter 
ac:name="language">xml</parameter><plain-text-body>&lt;a 
href="${profilePageLink}"&gt;Display Profile (w/ full details)&lt;/a&gt;
-</plain-text-body><p>In the matching Java class, you can create the Link 
programmatically:</p><parameter ac:name="controls">true</parameter><parameter 
ac:name="language">java</parameter><plain-text-body>  @Inject
+                <div id="ConfluenceContent"><h2 
id="LinkComponentsFAQ-LinkComponents">Link Components</h2><h3 
id="LinkComponentsFAQ-HowdoIaddqueryparameterstoaPageLinkorActionLink?">How do 
I add query parameters to a PageLink or ActionLink?</h3><p>These components do 
not have parameters to allow you to specify query parameters for the link; they 
both allow you to specify a <em>context</em> (one or more values to encode into 
the request path).</p><p>However, you can accomplish the same thing with a 
little code and markup. For example, to create a link to another page and pass 
a query parameter, you can replace your PageLink component with a standard 
<code>&lt;a&gt;</code> tag:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;a href="${profilePageLink}"&gt;Display Profile (w/ 
full details)&lt;/a&gt;
+</pre>
+</div></div><p>In the matching Java class, you can create the Link 
programmatically:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Inject
   private PageRenderLinkSource linkSource;
 
   public Link getProfilePageLink()
@@ -77,22 +90,27 @@
     link.addParameterValue("detail", true);
     return link;
   }
-</plain-text-body><p>... and in the DisplayProfile page:</p><parameter 
ac:name="controls">true</parameter><parameter 
ac:name="language">java</parameter><plain-text-body>public class DisplayProfile
+</pre>
+</div></div><p>... and in the DisplayProfile page:</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 DisplayProfile
 {
   void onActivate(@RequestParameter("detail") boolean detail)
   {
     . . .
   }
 }
-</plain-text-body><p>The @RequestParameter annotation directs Tapestry to 
extract the query parameter from the request and coerce it to type boolean. You 
can use any reasonable type for such a parameter (int, long and Date are 
common).</p><p>A similar technique can be used to add query parmeters to 
component event URLs (the type generated by the ActionLink or EventLink 
components), by injecting the ComponentResources, and invoking method 
<code>createEventLink()</code>.</p>
+</pre>
+</div></div><p>The @RequestParameter annotation directs Tapestry to extract 
the query parameter from the request and coerce it to type boolean. You can use 
any reasonable type for such a parameter (int, long and Date are 
common).</p><p>A similar technique can be used to add query parmeters to 
component event URLs (the type generated by the ActionLink or EventLink 
components), by injecting the ComponentResources, and invoking method 
<code>createEventLink()</code>.</p>
 
 <div class="confluence-information-macro 
confluence-information-macro-information"><p class="title">Added in 
5.3</p><span class="aui-icon aui-icon-small aui-iconfont-info 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body">
 </div></div>
 <div class="error"><span class="error">Unknown macro: {div}</span> 
 <p>You may also bind a link component's <code>parameters</code> parameter; 
this is a Map of additional query parameters to add to the URL.  The Map keys 
should be strings, and the Map values will be encoded to strings.  Tapestry 5.3 
also adds a literal map syntax to the <a  href="property-expressions.html" 
title="Property Expressions">property expression language</a>.</p>
 
-</div><h3 
id="LinkComponentsFAQ-HowdoIcreateaLinkbacktothecurrentpagefromacomponent?">How 
do I create a Link back to the current page from a component?</h3><p>Sometimes 
it is useful to create a link back to the current page, but you don't always 
know the name of the page (the link may appear inside a deeply nested 
subcomponent). Fortunately, this is easy.</p><parameter 
ac:name="language">xml</parameter><plain-text-body>&lt;t:pagelink 
page="prop:componentResources.pageName"&gt;refresh page&lt;/t:pagelink&gt;
-</plain-text-body><p>Every component has an extra property, 
componentResources, added to it: it's the instance of <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html";>ComponentResources</a>
 that represents the link between your code and all of Tapestry's structure 
around your class. One of the properties of ComponentResources is pageName, the 
name of the page. By binding the PageLink's page parameter with the "prop:" 
binding prefix, we ensure that we bind to a computed property; this is 
necessary because the PageLink.page parameter defaults to the "literal:" 
binding prefix.</p><p>As an added benefit, if the page class is ever renamed or 
moved to a different package, the pageName property will automatically adjust 
to the new name.</p><plain-text-body>{scrollbar}</plain-text-body></div>
+</div><h3 
id="LinkComponentsFAQ-HowdoIcreateaLinkbacktothecurrentpagefromacomponent?">How 
do I create a Link back to the current page from a component?</h3><p>Sometimes 
it is useful to create a link back to the current page, but you don't always 
know the name of the page (the link may appear inside a deeply nested 
subcomponent). Fortunately, this is easy.</p><div class="code panel pdl" 
style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;">&lt;t:pagelink 
page="prop:componentResources.pageName"&gt;refresh page&lt;/t:pagelink&gt;
+</pre>
+</div></div><p>Every component has an extra property, componentResources, 
added to it: it's the instance of <a  class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ComponentResources.html";>ComponentResources</a>
 that represents the link between your code and all of Tapestry's structure 
around your class. One of the properties of ComponentResources is pageName, the 
name of the page. By binding the PageLink's page parameter with the "prop:" 
binding prefix, we ensure that we bind to a computed property; this is 
necessary because the PageLink.page parameter defaults to the "literal:" 
binding prefix.</p><p>As an added benefit, if the page class is ever renamed or 
moved to a different package, the pageName property will automatically adjust 
to the new name.</p></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/localization.html
==============================================================================
--- websites/production/tapestry/content/localization.html (original)
+++ websites/production/tapestry/content/localization.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,32 +77,94 @@
       </div>
 
       <div id="content">
-                <div 
id="ConfluenceContent"><p>&#160;</p><p><strong>Localization</strong> (aka L10n) 
is all about getting the right text to the user, in the right 
language.</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 in 
("component-templates","localization") and space = 
currentSpace()</parameter></rich-text-body><p>Localization support is well 
integrated into Tapestry. Tapestry allows you to easily separate the text you 
present to your users from the rest of your application ... pull it out of your 
Java code and even out of your component templates. You can then translate your 
messages into other languages and let Tapestry put everything together.</p><h2 
id="Localization-Compon
 entMessageCatalogs">Component Message Catalogs</h2><p>Each component class may 
have a component message catalog. A component message catalog is a set of files 
with the extension ".properties". These property files are the same format used 
by java.util.ResourceBundle, just lines of <code>key=value</code>. These files 
are stored on the classpath, in the same package folder as the page or 
component's compiled Java class.</p><p>So for a class named 
<code>org.example.myapp.pages.MyPage</code>, you would have a main properties 
file as <code>org/example/myapp/pages/MyPage.properties</code>.</p><p>If you 
have a translations of these values, you provide additional properties file, 
adding an <a  class="external-link" 
href="http://www.loc.gov/standards/iso639-2/englangn.html"; rel="nofollow">ISO 
language code</a> before the extension. Thus, if you have a French translation, 
you could create a file <code>MyPage_fr.properties</code>.</p><p>Any values in 
the more language specific file will <em>ov
 erride</em> values from the main properties file. If you had an even more 
specific localization for just French as spoken in France, you could create 
<code>MyPage_fr_FR.properties</code> (that's a language code plus a country 
code, and you can even go further and add variants ... but its unlikely that 
you'll ever need to go beyond just language codes in practice).</p><p>The 
messages in the catalog are accessed by keys. Tapestry ignores the case of the 
keys when accessing messages in the catalog.</p><h3 
id="Localization-ComponentMessageCatalogInheritance">Component Message Catalog 
Inheritance</h3><p>If a component class is a subclass of another component 
class, then it inherits that base class' message catalog. Its own message 
catalog extends and overrides the values inherited from the base 
class.</p><p>In this way, you could have a base component class that contained 
common messages, and extend or override those messages in subclasses (just as 
you would extend or override the method
 s of the base component class). This, of course, works for as many levels of 
inheritance as you care to support.</p><h2 
id="Localization-Application-wideMessageCatalog">Application-wide Message 
Catalog</h2><p>If the file 
<code>WEB-INF/</code><em>AppName</em><code>.properties</code> exists in the 
context, it will be used as an application-wide message catalog. The 
<em>AppName</em> is derived from the name of the filter inside the web.xml 
file; this is most often just "app", thus <code>WEB-INF/app.properties</code>. 
The search for the file is case sensitive. The properties files may be 
localized.</p><p>Individual pages and components can override the values 
defined in the message catalog.<plain-text-body>{float:right|width=45%}
-{note:title=Avoid BOMs}
-Make sure that your properties files don't contain [byte order marks 
(BOM)|http://en.wikipedia.org/wiki/Byte_order_mark], because Java -- and thus 
Tapestry -- doesn't support BOM in properties files (see 
http://bugs.sun.com/view_bug.do?bug_id=4508058). Some editors write them out 
when saving a file in UTF-8, so watch out.
-{note}
-{float}</plain-text-body></p><h2 
id="Localization-PropertiesFileCharset">Properties File Charset</h2><p>Tapestry 
uses the <code>UTF-8</code> character set (charset) when reading the properties 
files in a message catalog. This means that you don't have to use the Java 
<code>native2ascii</code> tool.</p><h2 
id="Localization-LocalizedComponentTemplates">Localized Component 
Templates</h2><p>The same lookup mechanism applies to component templates. 
Tapestry will search for a localized version of each component template and use 
the closest match. Thus you could have <code>MyPage_fr.html</code> for French 
users, and <code>MyPage.html</code> for all other users.</p><h2 
id="Localization-AccessingLocalizedMessages">Accessing Localized 
Messages</h2><p>The above discusses what files to create and where to store 
them, but doesn't address how to make use of that information.</p><p>Messages 
can be accessed in one of two ways:</p><ul><li>Using the "message:" <a  
href="component-parameters.html">bin
 ding expression</a> in a component template</li><li>By injecting the 
component's Messages object<br clear="none"> In the first case, you may use the 
message: binding prefix with component parameters, or with template 
expansions:</li></ul><parameter 
ac:name="">java</parameter><plain-text-body>&lt;t:layout 
title="message:page-title"&gt;
+                <div 
id="ConfluenceContent"><p>&#160;</p><p><strong>Localization</strong> (aka L10n) 
is all about getting the right text to the user, in the right language.</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="templating-and-markup-faq.html">Templating 
and Markup FAQ</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-classes.html">Component Classes</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="localization.html">Localization</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>Localization support is well integrated into Tapestry. Tapestry allows you 
to easily separate the text you present to your users from the rest of your 
application ... pull it out of your Java code and even out of your component 
templates. You can then translate your messages into other languages and let 
Tapestry put everything together.</p><h2 
id="Localization-ComponentMessageCatalogs">Component Message 
Catalogs</h2><p>Each component class may have a component message catalog. A 
component message catalog is a set of files with the extension ".properties". 
These property files are the same format used by java.util.ResourceBundle, just 
lines of <code>key=value</code>. These files are stored on the classpath, in 
the same package folder as the page or component's compiled Java 
class.</p><p>So for a class named <code>org.example.myapp.pages.MyPage</code>, 
you would have a main properties file as 
<code>org/example/myapp/pages/MyPage.properties</code>.</p><p>If you have a 
translations o
 f these values, you provide additional properties file, adding an <a  
class="external-link" 
href="http://www.loc.gov/standards/iso639-2/englangn.html"; rel="nofollow">ISO 
language code</a> before the extension. Thus, if you have a French translation, 
you could create a file <code>MyPage_fr.properties</code>.</p><p>Any values in 
the more language specific file will <em>override</em> values from the main 
properties file. If you had an even more specific localization for just French 
as spoken in France, you could create <code>MyPage_fr_FR.properties</code> 
(that's a language code plus a country code, and you can even go further and 
add variants ... but its unlikely that you'll ever need to go beyond just 
language codes in practice).</p><p>The messages in the catalog are accessed by 
keys. Tapestry ignores the case of the keys when accessing messages in the 
catalog.</p><h3 id="Localization-ComponentMessageCatalogInheritance">Component 
Message Catalog Inheritance</h3><p>If a component clas
 s is a subclass of another component class, then it inherits that base class' 
message catalog. Its own message catalog extends and overrides the values 
inherited from the base class.</p><p>In this way, you could have a base 
component class that contained common messages, and extend or override those 
messages in subclasses (just as you would extend or override the methods of the 
base component class). This, of course, works for as many levels of inheritance 
as you care to support.</p><h2 
id="Localization-Application-wideMessageCatalog">Application-wide Message 
Catalog</h2><p>If the file 
<code>WEB-INF/</code><em>AppName</em><code>.properties</code> exists in the 
context, it will be used as an application-wide message catalog. The 
<em>AppName</em> is derived from the name of the filter inside the web.xml 
file; this is most often just "app", thus <code>WEB-INF/app.properties</code>. 
The search for the file is case sensitive. The properties files may be 
localized.</p><p>Individual pages 
 and components can override the values defined in the message catalog.</p><div 
class="navmenu" style="float:right; width:45%; background:white; margin:3px; 
padding:3px">
+<div class="confluence-information-macro confluence-information-macro-note"><p 
class="title">Avoid BOMs</p><span class="aui-icon aui-icon-small 
aui-iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body">
+<p>Make sure that your properties files don't contain <a  
class="external-link" href="http://en.wikipedia.org/wiki/Byte_order_mark"; 
rel="nofollow">byte order marks (BOM)</a>, because Java &#8211; and thus 
Tapestry &#8211; doesn't support BOM in properties files (see <a  
class="external-link" href="http://bugs.sun.com/view_bug.do?bug_id=4508058"; 
rel="nofollow">http://bugs.sun.com/view_bug.do?bug_id=4508058</a>). Some 
editors write them out when saving a file in UTF-8, so watch 
out.</p></div></div></div><h2 
id="Localization-PropertiesFileCharset">Properties File Charset</h2><p>Tapestry 
uses the <code>UTF-8</code> character set (charset) when reading the properties 
files in a message catalog. This means that you don't have to use the Java 
<code>native2ascii</code> tool.</p><h2 
id="Localization-LocalizedComponentTemplates">Localized Component 
Templates</h2><p>The same lookup mechanism applies to component templates. 
Tapestry will search for a localized version of each component template
  and use the closest match. Thus you could have <code>MyPage_fr.html</code> 
for French users, and <code>MyPage.html</code> for all other users.</p><h2 
id="Localization-AccessingLocalizedMessages">Accessing Localized 
Messages</h2><p>The above discusses what files to create and where to store 
them, but doesn't address how to make use of that information.</p><p>Messages 
can be accessed in one of two ways:</p><ul><li>Using the "message:" <a  
href="component-parameters.html">binding expression</a> in a component 
template</li><li>By injecting the component's Messages object<br clear="none"> 
In the first case, you may use the message: binding prefix with component 
parameters, or with template expansions:</li></ul><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;">&lt;t:layout title="message:page-title"&gt;
 
   ${message:greeting}, ${user.name}!
   
   . . .
 &lt;/t:layout&gt;
-</plain-text-body><p>Here, the <code>page-title</code> message is extracted 
from the catalog and passed to the Border component's title parameter.</p><p>In 
addition, the <code>greeting</code> message is extracted and written into the 
response as part of the template.</p><p>As usual, "prop:" is the default 
binding prefix, thus <code>user.name</code> is a property path, not a message 
key.</p><p>You would extend this with a set of properties files:</p><parameter 
ac:name="">java</parameter><plain-text-body>page-title=Your Account
+</pre>
+</div></div><p>Here, the <code>page-title</code> message is extracted from the 
catalog and passed to the Border component's title parameter.</p><p>In 
addition, the <code>greeting</code> message is extracted and written into the 
response as part of the template.</p><p>As usual, "prop:" is the default 
binding prefix, thus <code>user.name</code> is a property path, not a message 
key.</p><p>You would extend this with a set of properties files:</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;">page-title=Your Account
 greeting=Welcome back
-</plain-text-body><p>Or, perhaps, a French version:</p><parameter 
ac:name="">java</parameter><plain-text-body>page-title=Votre Compte
+</pre>
+</div></div><p>Or, perhaps, a French version:</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;">page-title=Votre Compte
 greeting=Bienvenue en arriere
-</plain-text-body><p>Programatically, you may inject your component message 
catalog into your class, as an instance of the Messages 
interface:</p><parameter ac:name="">java</parameter><plain-text-body>  @Inject
+</pre>
+</div></div><p>Programatically, you may inject your component message catalog 
into your class, as an instance of the Messages interface:</p><div class="code 
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  @Inject
   private Messages messages;
-</plain-text-body><p>You could then <code>get()</code> messages, or 
<code>format()</code> them:</p><parameter 
ac:name="">java</parameter><plain-text-body>  public String getCartSummary()    
 
+</pre>
+</div></div><p>You could then <code>get()</code> messages, or 
<code>format()</code> them:</p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">  public String getCartSummary()     
   {
     if (items.isEmpty())
       return messages.get("no-items");
       
     return messages.format("item-summary", _items.size());
   }
-</plain-text-body><p>The format() option works using a 
<code>java.util.Formatter</code>, with all the printf-style loveliness you've 
come to expect:</p><parameter 
ac:name="">java</parameter><plain-text-body>no-items=Your shopping cart is 
empty.     
+</pre>
+</div></div><p>The format() option works using a 
<code>java.util.Formatter</code>, with all the printf-style loveliness you've 
come to expect:</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;">no-items=Your shopping cart is empty.     
 item-summary=You have %d items in your cart.
-</plain-text-body><p>As easy as conditionals are to use inside a Tapestry 
template, sometimes it's even easier to do it in Java code.</p><h2 
id="Localization-MissingKeys">Missing Keys</h2><p>If you reference a key that 
is not in the message catalog, Tapestry does not throw an exception (because 
that would make initially developing an application very frustrating). When a 
key can not be located, a "placeholder" message is generated, such as 
"[[missing key: key-not-found]]".</p><h2 
id="Localization-Reloading">Reloading</h2><p>If you change a property file in a 
message catalog, you'll see the change immediately, just as with component 
classes and component templates (provided you're not running in <a  
href="configuration.html">production mode</a>).</p><h2 
id="Localization-AssetLocalization">Asset Localization</h2><p>When <a  
href="injection.html">injecting assets</a>, the injected asset will be 
localized as well. A search for the closest match for the active locale is 
made, and the fin
 al Asset will reflect that.</p><h2 id="Localization-LocaleSelection">Locale 
Selection</h2><p>The locale for each request is determined from the HTTP 
request headers. The request locale reflects the environment of the web browser 
and possibly even the keyboard selection of the user on the client. It can be 
highly specific, for example, identifying British English (as en_GB) vs. 
American English (en).</p><p>Tapestry "narrows" the raw request locale, as 
specified in the request, to a known quantity. It uses the <a  
href="configuration.html">configuration symbol</a> 
<code>tapestry.supported-locales</code> to choose the effective locale for each 
request. This value is a comma-separated list of locale names. Tapestry 
searches the list for the best match for the request locale; for example, a 
request locale of "fr_FR" would match "fr" but not "de". If no match is found, 
then the first locale name in the list is used as the effective locale (that 
is, the first locale is used as the default 
 for non-matching requests). Thus a site that primarily caters to French 
speakers would want to list "fr" as the first locale in the list.</p><h2 
id="Localization-ChangingtheLocale">Changing the Locale</h2><p>The <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/PersistentLocale.html";>PersistentLocale
 service</a> can be used to programmatically override the locale. Note: You 
should be careful to only set the persistent locale to a supported 
locale.</p><parameter ac:name="">java</parameter><parameter 
ac:name="title">Toggle between English and 
German</parameter><plain-text-body>@Inject 
+</pre>
+</div></div><p>As easy as conditionals are to use inside a Tapestry template, 
sometimes it's even easier to do it in Java code.</p><h2 
id="Localization-MissingKeys">Missing Keys</h2><p>If you reference a key that 
is not in the message catalog, Tapestry does not throw an exception (because 
that would make initially developing an application very frustrating). When a 
key can not be located, a "placeholder" message is generated, such as 
"[[missing key: key-not-found]]".</p><h2 
id="Localization-Reloading">Reloading</h2><p>If you change a property file in a 
message catalog, you'll see the change immediately, just as with component 
classes and component templates (provided you're not running in <a  
href="configuration.html">production mode</a>).</p><h2 
id="Localization-AssetLocalization">Asset Localization</h2><p>When <a  
href="injection.html">injecting assets</a>, the injected asset will be 
localized as well. A search for the closest match for the active locale is 
made, and the final Ass
 et will reflect that.</p><h2 id="Localization-LocaleSelection">Locale 
Selection</h2><p>The locale for each request is determined from the HTTP 
request headers. The request locale reflects the environment of the web browser 
and possibly even the keyboard selection of the user on the client. It can be 
highly specific, for example, identifying British English (as en_GB) vs. 
American English (en).</p><p>Tapestry "narrows" the raw request locale, as 
specified in the request, to a known quantity. It uses the <a  
href="configuration.html">configuration symbol</a> 
<code>tapestry.supported-locales</code> to choose the effective locale for each 
request. This value is a comma-separated list of locale names. Tapestry 
searches the list for the best match for the request locale; for example, a 
request locale of "fr_FR" would match "fr" but not "de". If no match is found, 
then the first locale name in the list is used as the effective locale (that 
is, the first locale is used as the default for no
 n-matching requests). Thus a site that primarily caters to French speakers 
would want to list "fr" as the first locale in the list.</p><h2 
id="Localization-ChangingtheLocale">Changing the Locale</h2><p>The <a  
class="external-link" 
href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/PersistentLocale.html";>PersistentLocale
 service</a> can be used to programmatically override the locale. Note: You 
should be careful to only set the persistent locale to a supported 
locale.</p><div class="code panel pdl" style="border-width: 1px;"><div 
class="codeHeader panelHeader pdl" style="border-bottom-width: 1px;"><b>Toggle 
between English and German</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">@Inject 
 private PersistentLocale persistentLocale;
 
 void onActionFromLocaleToggle() {
@@ -106,8 +178,9 @@ void onActionFromLocaleToggle() {
 public String getDisplayLanguage() {
     return persistentLocale.get().getDisplayLanguage();
 }
-</plain-text-body><p>Once a persistent locale is set, you will see the locale 
name as the first virtual folder in page render and component event requests 
URLs. In this way, a persistent locale will, in fact, persist from request to 
request, or in a user's bookmarks.</p><p>You will see the new locale take 
effect on the next request. If it is changed in a component event request 
(which is typical), the new locale will be used in the subsequent page render 
request.</p><p>Note that the locale for a page is fixed (it can't change once 
the page instance is created). In addition, a page may only be attached to a 
request once. In other words, if code in your page changes the persistent 
locale, you won't see a change to the page's locale (or localized messages) 
<em>in that request</em>.</p><h2 id="Localization-Built-inLocales">Built-in 
Locales</h2><p>While your application can support any locale (and thus any 
language) that you want, Tapestry provides only a limited set of translations 
for 
 its own built-in messages. As of Tapestry 5.3, the following locales have 
translations provided:</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>en (English)</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>el (Greek)</span></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>it (Italian)</span></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>pl 
(Polish)</span></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span><span>sv 
(Swedish)</span></span></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>bg (Bulgarian)</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>es (Spanish)</span></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>ja (Japanese)</span></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>pt 
(Portuguese)</span></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>
 <span>vi (Vietnamese)</span></span></p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p>cs (Czech)<sup>1</sup></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>fi 
(Finnish)</span></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>mk (Macedonian)</span></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>ru (Russian)</span></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>zh 
(Chinese)</span></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>da (Danish)</span></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>fr (French)</span></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>nl 
(Dutch)</span></p></td><td colspan="1" rowspan="1" class="confluenceTd">sl 
(Slovenian)<sup>2</sup></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&#160;</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>de (German)</span></p></td><td colspa
 n="1" rowspan="1" class="confluenceTd"><p><span>hr 
(Croatian)</span></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>no (Norwegian)</span></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>sr (Serbian)</span></p></td><td 
colspan="1" rowspan="1" 
class="confluenceTd"><p>&#160;</p></td></tr></tbody></table></div><p><sup>1&#160;</sup><span
 style="line-height: 1.4285715;">as of Tapestry 5.3.8</span></p><p><span 
style="line-height: 1.4285715;">&#160;</span><sup>2 </sup><span>as of Tapestry 
5.4</span></p><h3 
id="Localization-ProvidingtranslationsforTapestrybuilt-inmessages">Providing 
translations for Tapestry built-in messages</h3><p>Fortunately, Tapestry uses 
all the same mechanisms for its own locale support as it provides for your 
application. So, to support other locales, just translate the built-in message 
catalog (property) files yourself:</p><p>&#160;</p><parameter 
ac:name="atlassian-macro-output-type">BLOCK</parameter><plain-text-body>&lt;style
 typ
 e="text/css"&gt;table.sectionMacro { width: auto; }&lt;/style&gt;
-</plain-text-body><parameter 
ac:name="width">auto</parameter><rich-text-body><rich-text-body><div 
class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" 
rowspan="1" class="confluenceTh"><p>Tapestry 5.4 and later</p></th></tr><tr><td 
colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree;f=tapestry-core/src/main/resources/org/apache/tapestry5";>core.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree;f=tapestry-kaptcha/src/main/resources/org/apache/tapestry5/kaptcha";>tapestry-kaptcha.properties</a></p></td></tr></tbody></table></div></rich-text-body><rich-text-body><div
 class="table-wrap"><table class="confluenceTable"><tbody><tr><th colspan="1" 
rowspan="1" class="confluenceTh"><p>Tapestry 5.3.x</p></th></tr><tr><td 
colspan="1" rowspan="1" class="con
 fluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.properties?view=markup";>BeanEditForm.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/DateField.properties?view=markup";>DateField.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Errors.properties?view=markup";>Errors.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry
 
-core/src/main/resources/org/apache/tapestry5/corelib/components/GridColumns.properties?view=markup">GridColumns.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/GridPager.properties?view=markup";>GridPager.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Palette.properties?view=markup";>Palette.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages.properties?view=markup";>ValidationMessage
 s.properties</a></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-kaptcha/src/main/resources/org/apache/tapestry5/kaptcha/tapestry-kaptcha.properties?view=markup";>tapestry-kaptcha.properties</a></p></td></tr></tbody></table></div></rich-text-body></rich-text-body><p>To
 have Tapestry use these new files, just put them in the corresponding 
package-named directory within your own app (for example, 
src/main/resources/org/apache/tapestry5/core.properties).</p><p>Finally, please 
open a new feature request <a  class="external-link" 
href="https://issues.apache.org/jira/browse/TAP5";>here</a> and attach the 
translated files so that they can be included in the next release of 
Tapestry.</p><rich-text-body><p>Please note that a patch is always preferred 
over an archive of properties files.</p></rich-text-body></div>
+</pre>
+</div></div><p>Once a persistent locale is set, you will see the locale name 
as the first virtual folder in page render and component event requests URLs. 
In this way, a persistent locale will, in fact, persist from request to 
request, or in a user's bookmarks.</p><p>You will see the new locale take 
effect on the next request. If it is changed in a component event request 
(which is typical), the new locale will be used in the subsequent page render 
request.</p><p>Note that the locale for a page is fixed (it can't change once 
the page instance is created). In addition, a page may only be attached to a 
request once. In other words, if code in your page changes the persistent 
locale, you won't see a change to the page's locale (or localized messages) 
<em>in that request</em>.</p><h2 id="Localization-Built-inLocales">Built-in 
Locales</h2><p>While your application can support any locale (and thus any 
language) that you want, Tapestry provides only a limited set of translations 
for its ow
 n built-in messages. As of Tapestry 5.3, the following locales have 
translations provided:</p><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>en (English)</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>el (Greek)</span></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>it (Italian)</span></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>pl 
(Polish)</span></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span><span>sv 
(Swedish)</span></span></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>bg (Bulgarian)</p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>es (Spanish)</span></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>ja (Japanese)</span></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>pt 
(Portuguese)</span></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span><span>
 vi (Vietnamese)</span></span></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p>cs (Czech)<sup>1</sup></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>fi (Finnish)</span></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>mk 
(Macedonian)</span></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>ru (Russian)</span></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>zh 
(Chinese)</span></p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>da (Danish)</span></p></td><td colspan="1" 
rowspan="1" class="confluenceTd"><p><span>fr (French)</span></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>nl 
(Dutch)</span></p></td><td colspan="1" rowspan="1" class="confluenceTd">sl 
(Slovenian)<sup>2</sup></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p>&#160;</p></td></tr><tr><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>de (German)</span></p></td><td colspan="1" 
 rowspan="1" class="confluenceTd"><p><span>hr (Croatian)</span></p></td><td 
colspan="1" rowspan="1" class="confluenceTd"><p><span>no 
(Norwegian)</span></p></td><td colspan="1" rowspan="1" 
class="confluenceTd"><p><span>sr (Serbian)</span></p></td><td colspan="1" 
rowspan="1" 
class="confluenceTd"><p>&#160;</p></td></tr></tbody></table></div><p><sup>1&#160;</sup><span
 style="line-height: 1.4285715;">as of Tapestry 5.3.8</span></p><p><span 
style="line-height: 1.4285715;">&#160;</span><sup>2 </sup><span>as of Tapestry 
5.4</span></p><h3 
id="Localization-ProvidingtranslationsforTapestrybuilt-inmessages">Providing 
translations for Tapestry built-in messages</h3><p>Fortunately, Tapestry uses 
all the same mechanisms for its own locale support as it provides for your 
application. So, to support other locales, just translate the built-in message 
catalog (property) files yourself:</p><p>&#160;</p><style 
type="text/css">table.sectionMacro { width: auto; }</style>
+<div class="sectionColumnWrapper"><div class="sectionMacro"><div 
class="sectionMacroRow"><div class="columnMacro"><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry 5.4 and later</p></th></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree;f=tapestry-core/src/main/resources/org/apache/tapestry5";>core.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="https://git-wip-us.apache.org/repos/asf?p=tapestry-5.git;a=tree;f=tapestry-kaptcha/src/main/resources/org/apache/tapestry5/kaptcha";>tapestry-kaptcha.properties</a></p></td></tr></tbody></table></div></div><div
 class="columnMacro"><div class="table-wrap"><table 
class="confluenceTable"><tbody><tr><th colspan="1" rowspan="1" 
class="confluenceTh"><p>Tapestry 5.3.x</p></th></tr><tr><td colspan="1" row
 span="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.properties?view=markup";>BeanEditForm.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/DateField.properties?view=markup";>DateField.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Errors.properties?view=markup";>Errors.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/br
 
anches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/GridColumns.properties?view=markup">GridColumns.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/GridPager.properties?view=markup";>GridPager.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/Palette.properties?view=markup";>Palette.properties</a></p></td></tr><tr><td
 colspan="1" rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages.properties?view=markup
 ">ValidationMessages.properties</a></p></td></tr><tr><td colspan="1" 
rowspan="1" class="confluenceTd"><p><a  class="external-link" 
href="http://svn.apache.org/viewvc/tapestry/tapestry5/branches/5.3/tapestry-kaptcha/src/main/resources/org/apache/tapestry5/kaptcha/tapestry-kaptcha.properties?view=markup";>tapestry-kaptcha.properties</a></p></td></tr></tbody></table></div></div></div></div></div><p>To
 have Tapestry use these new files, just put them in the corresponding 
package-named directory within your own app (for example, 
src/main/resources/org/apache/tapestry5/core.properties).</p><p>Finally, please 
open a new feature request <a  class="external-link" 
href="https://issues.apache.org/jira/browse/TAP5";>here</a> and attach the 
translated files so that they can be included in the next release of 
Tapestry.</p><div class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span
 ><div class="confluence-information-macro-body"><p>Please note that a patch is 
 >always preferred over an archive of properties files.</p></div></div></div>
       </div>
 
       <div class="clearer"></div>

Modified: websites/production/tapestry/content/logging-in-tapestry.html
==============================================================================
--- websites/production/tapestry/content/logging-in-tapestry.html (original)
+++ websites/production/tapestry/content/logging-in-tapestry.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/shBrushXml.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">Logging in Tapestry</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">Logging in Tapestry</h1></div></div>
       <div class="clearer"></div>
       </div>
 
@@ -67,7 +62,20 @@
       </div>
 
       <div id="content">
-                <div id="ConfluenceContent"><p><strong>Logging in 
Tapestry</strong> is based on the <a  class="external-link" 
href="http://www.slf4j.org/"; rel="nofollow">Simple Logging Facade for Java 
(SLF4J)</a>. You can think of SLF4J as a leaner, meaner replacement for <a  
class="external-link" 
href="http://commons.apache.org/logging/";>commons-logging</a>.</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 = "logging" and space = 
currentSpace()</parameter></rich-text-body><p>In theory, SLF4J is a wrapper 
around any of a number of logging systems, including <a  class="external-link" 
href="http://logging.apache.org/log4j/1.2/";>Log4J</a> or the built-in JDK 
logging. In practice, it is
  almost always used with Log4J and no additional build configuration is 
needed.</p><p>Your application <em>will</em> need to provide a 
<strong>log4j.properties</strong> file (or its XML equivalent). See <a  
class="external-link" 
href="http://logging.apache.org/log4j/1.2/manual.html";>the Log4J manual</a> for 
more information.</p><h1 id="LogginginTapestry-AccessingLoggers">Accessing 
Loggers</h1><p>Loggers are a special kind of resource that is injected into a 
service. In Tapestry IoC, Loggers an be injected into service constructors, or 
into service builder methods.</p><p>In Tapestry Core (the web framework), 
Loggers for components can be injected into component fields.</p><p>This often 
confuses people, because the standard idiom is to create a Logger based on the 
class name and inject it into a static field. In Tapestry, the Logger is 
created on your code's behalf and provided to you, and stored into a final 
private field.</p><p>In terms of separation of concerns, Tapestry's approach
  is superior ... the concern of creating loggers is offloaded into the 
framework, and you code retains the concern of actually logging useful 
information. However this is largely theoretical.</p><p>For a pragmatic 
standpoint, injecting Loggers makes it easier to test <em>logging</em> code 
using the same techniques used to test other code: via the injection of Mock 
Object implementations of the Logger interface. This is something to consider 
when writing your own services, components and test.</p><h1 
id="LogginginTapestry-ServiceLogging">Service Logging</h1><p>Tapestry uses the 
same loggers that are injected into services; it logs, at debug level, details 
about the construction of the service (and the proxy for the service), 
including details such as methods invoked.</p><h1 
id="LogginginTapestry-OperationTracker">Operation Tracker</h1><p>The 
OperationTracker is a resource available throughout Tapestry that is used to 
track what Tapestry is doing at any given time. Normally, this info
 rmation is only used when reporting errors, as it gives an indication of what 
Tapestry was doing leading up to the point where the exception 
occurred.</p><p>Starting in Tapestry 5.3, you may also enable debug logging for 
<code>org.apache.tapestry5.ioc.Registry</code> to see voluminous details on 
creation of proxies, services, injections, and so forth. It also tracks 
creation of pages and components, triggering of component events, handling of 
return values from event handler methods, and many (many!) other 
details.</p><p>The logging even identifies how long each operation takes. This 
can be useful for understanding what is going on in a Tapestry application 
during the processing of the request, it can also be useful when tracking down 
performance issues.</p><p>An example from the startup of a Tapestry 
application:</p><plain-text-body>[INFO] RegistryBuilder Adding module 
definition for class org.apache.tapestry5.services.TapestryModule
+                <div id="ConfluenceContent"><p><strong>Logging in 
Tapestry</strong> is based on the <a  class="external-link" 
href="http://www.slf4j.org/"; rel="nofollow">Simple Logging Facade for Java 
(SLF4J)</a>. You can think of SLF4J as a leaner, meaner replacement for <a  
class="external-link" 
href="http://commons.apache.org/logging/";>commons-logging</a>.</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="logging-in-tapestry.html">Logging in Tapestry</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="logging.html">Logging</a> 
+  </div> </li></ul></div><p>In theory, SLF4J is a wrapper around any of a 
number of logging systems, including <a  class="external-link" 
href="http://logging.apache.org/log4j/1.2/";>Log4J</a> or the built-in JDK 
logging. In practice, it is almost always used with Log4J and no additional 
build configuration is needed.</p><p>Your application <em>will</em> need to 
provide a <strong>log4j.properties</strong> file (or its XML equivalent). See 
<a  class="external-link" 
href="http://logging.apache.org/log4j/1.2/manual.html";>the Log4J manual</a> for 
more information.</p><h1 id="LogginginTapestry-AccessingLoggers">Accessing 
Loggers</h1><p>Loggers are a special kind of resource that is injected into a 
service. In Tapestry IoC, Loggers an be injected into service constructors, or 
into service builder methods.</p><p>In Tapestry Core (the web framework), 
Loggers for components can be injected into component fields.</p><p>This often 
confuses people, because the standard idiom is to create a Logger
  based on the class name and inject it into a static field. In Tapestry, the 
Logger is created on your code's behalf and provided to you, and stored into a 
final private field.</p><p>In terms of separation of concerns, Tapestry's 
approach is superior ... the concern of creating loggers is offloaded into the 
framework, and you code retains the concern of actually logging useful 
information. However this is largely theoretical.</p><p>For a pragmatic 
standpoint, injecting Loggers makes it easier to test <em>logging</em> code 
using the same techniques used to test other code: via the injection of Mock 
Object implementations of the Logger interface. This is something to consider 
when writing your own services, components and test.</p><h1 
id="LogginginTapestry-ServiceLogging">Service Logging</h1><p>Tapestry uses the 
same loggers that are injected into services; it logs, at debug level, details 
about the construction of the service (and the proxy for the service), 
including details such as
  methods invoked.</p><h1 id="LogginginTapestry-OperationTracker">Operation 
Tracker</h1><p>The OperationTracker is a resource available throughout Tapestry 
that is used to track what Tapestry is doing at any given time. Normally, this 
information is only used when reporting errors, as it gives an indication of 
what Tapestry was doing leading up to the point where the exception 
occurred.</p><p>Starting in Tapestry 5.3, you may also enable debug logging for 
<code>org.apache.tapestry5.ioc.Registry</code> to see voluminous details on 
creation of proxies, services, injections, and so forth. It also tracks 
creation of pages and components, triggering of component events, handling of 
return values from event handler methods, and many (many!) other 
details.</p><p>The logging even identifies how long each operation takes. This 
can be useful for understanding what is going on in a Tapestry application 
during the processing of the request, it can also be useful when tracking down 
performance is
 sues.</p><p>An example from the startup of a Tapestry application:</p><div 
class="preformatted panel" style="border-width: 1px;"><div 
class="preformattedContent panelContent">
+<pre>[INFO] RegistryBuilder Adding module definition for class 
org.apache.tapestry5.services.TapestryModule
 [INFO] RegistryBuilder Adding module definition for class 
org.apache.tapestry5.internal.services.InternalModule
 [INFO] RegistryBuilder Adding module definition for class 
org.apache.tapestry5.services.assets.AssetsModule
 [INFO] RegistryBuilder Adding module definition for class 
org.apache.tapestry5.services.pageload.PageLoadModule
@@ -111,7 +119,9 @@
 [DEBUG] Registry [ 11] &lt;-- Determining injection value for parameter #1 
(org.apache.tapestry5.ioc.OrderedConfiguration) [0.11 ms]
 [DEBUG] Registry [ 11] --&gt; Determining injection value for parameter #2 
(org.apache.tapestry5.ioc.ObjectProvider)
 . . .
-</plain-text-body><h1 
id="LogginginTapestry-ConfiguringTapestryforotherLoggingToolkits">Configuring 
Tapestry for other Logging Toolkits</h1><p>The default configuration uses 
Log4J.</p><p>If you need to use another logging system, that can be 
accomplished using Maven dependency control.</p><p>You can exclude some of the 
dependencies that Tapestry introduces, and replace them with your own. For 
example, to switch over to JDK logging, update your pom as 
follows:</p><parameter ac:name="language">xml</parameter><plain-text-body> 
+</pre>
+</div></div><h1 
id="LogginginTapestry-ConfiguringTapestryforotherLoggingToolkits">Configuring 
Tapestry for other Logging Toolkits</h1><p>The default configuration uses 
Log4J.</p><p>If you need to use another logging system, that can be 
accomplished using Maven dependency control.</p><p>You can exclude some of the 
dependencies that Tapestry introduces, and replace them with your own. For 
example, to switch over to JDK logging, update your pom as follows:</p><div 
class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" 
style="font-size:12px;"> 
   &lt;dependencies&gt;
     &lt;dependency&gt;
       &lt;groupId&gt;org.apache.tapestry&lt;/groupId&gt;
@@ -138,7 +148,8 @@
           &lt;version&gt;1.4.3&lt;/version&gt;
     &lt;/dependency&gt;
   &lt;/dependencies&gt;
-</plain-text-body><p>This pulls out the log4j support normally included with 
Tapestry, and replaces it with the SLF4J library that wraps around JDK 1.4 
logging.</p><p>In all likelihood, you'll replace <em>tapestry-ioc</em> with 
<em>tapestry-core</em> (assuming you are building a web application using 
Tapestry, rather than using Tapestry IoC as part of some other application). 
And, of course, version numbers change all the 
time!</p><p>&#160;</p><p></p></div>
+</pre>
+</div></div><p>This pulls out the log4j support normally included with 
Tapestry, and replaces it with the SLF4J library that wraps around JDK 1.4 
logging.</p><p>In all likelihood, you'll replace <em>tapestry-ioc</em> with 
<em>tapestry-core</em> (assuming you are building a web application using 
Tapestry, rather than using Tapestry IoC as part of some other application). 
And, of course, version numbers change all the 
time!</p><p>&#160;</p><p></p></div>
       </div>
 
       <div class="clearer"></div>


Reply via email to