Author: buildbot
Date: Sun Dec 22 15:11:52 2024
New Revision: 1088327
Log:
Production update by buildbot for tapestry
Modified:
websites/production/tapestry/content/cache/main.pageCache
websites/production/tapestry/content/localization.html
Modified: websites/production/tapestry/content/cache/main.pageCache
==============================================================================
Binary files - no diff available.
Modified: websites/production/tapestry/content/localization.html
==============================================================================
--- websites/production/tapestry/content/localization.html (original)
+++ websites/production/tapestry/content/localization.html Sun Dec 22 15:11:52
2024
@@ -143,7 +143,7 @@
<!-- /// Content Start -->
<div id="content">
- <div
id="ConfluenceContent"><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">
+ <div
id="ConfluenceContent"><p></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">
@@ -196,7 +196,7 @@
</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 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 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 a
nd components can override the values defined in the message catalog.</p><div
class="confluence-information-macro confluence-information-macro-warning"><p
class="title conf-macro-render">Avoid BOMs</p><span class="aui-icon
aui-icon-small aui-iconfont-error
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 – and thus Tapestry –
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><h2 id="Localization-PropertiesFileCharset">Properties File
Charset</h2><p>Tapestry uses the <code>UTF-8</code> character set (charset) w
hen 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 In the first
case, you may use the message: binding prefix with compon
ent parameters, or with template expansions:</li></ul><div class="code panel
pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
+<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 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 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 a
nd components can override the values defined in the message catalog.</p><div
class="confluence-information-macro confluence-information-macro-warning"><p
class="title conf-macro-render">Avoid BOMs</p><span class="aui-icon
aui-icon-small aui-iconfont-error
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 – and thus Tapestry –
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><p></p><h2
id="Localization-PropertiesFileCharset">Properties File Charset</h2><p>Tapestry
uses the <code>UTF-8</code> character set (cha
rset) 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 objectIn 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><code class="language-java"><t:layout title="message:page-title">
${message:greeting}, ${user.name}!
@@ -204,7 +204,7 @@
. . .
</t:layout>
</code></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">
+</div></div><p>Here, the <code>page-title</code> message is extracted from the
catalog and passed to the Layout component's
<code>title</code> 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><code class="language-java">page-title=Your Account
greeting=Welcome back
</code></pre>
@@ -245,7 +245,7 @@ public String getDisplayLanguage() {
return persistentLocale.get().getDisplayLanguage();
}
</code></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="table
table-bordered table-responsive"><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="conflue
nceTd"><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"></td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p><span>de (German)</span></p></td><td col
span="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"></td></tr></tbody></table></div><p><sup>1 </sup><span>as
of Tapestry 5.3.8</span></p><p><span> </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><style type="text/css">table.sectionMacro
{ width: auto; }</style>
+</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="table
table-bordered table-responsive"><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="conflue
nceTd"><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></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></p></td></tr></tbody></table></div><p><sup>1 </sup><span>as
of Tapestry 5.3.8</span></p><p><span> </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></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="table table-bordered table-responsive"><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="table table-bordered
table-responsive"><tbody><tr><th colspan="1" rowspan="1"
class="confluenceTh"><p>Tapestry
5.3.x</p></th></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/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.a
pache.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/Valida
tionMessages.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 confluen
ce-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>
<!-- /// Content End -->