incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling Website > Internationalization Support (i18n)
Date Thu, 17 Dec 2009 13:47:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=SLINGxSITE&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/SLINGxSITE/Internationalization+Support+%28i18n%29">Internationalization
Support (i18n)</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~fmeschbe">Felix
Meschberger</a>
    </h4>
     Adapt names of core implementations in Sling Engine (used to be called Sling Core)
          <div id="versionComment" class="noteMacro" style="display:none; padding: 5px;">
     Adapt names of core implementations in Sling Engine (used to be called Sling Core)<br
/>
     </div>
          <br/>
     <div class="notificationGreySide">
         <h1><a name="InternationalizationSupport%28i18n%29-InternationalizationSupport"></a>Internationalization
Support</h1>

<p>Internationalization support in Sling consists of four methods in the <tt>SlingHttpServletRequest</tt>
interface:</p>

<ul>
	<li><tt>getLocale()</tt> &#8211; Returns the primary <tt>Locale</tt>
for the current request. This method is inherited from the <tt>javax.servlet.ServletRequest</tt>
interface.</li>
	<li><tt>getLocales()</tt> &#8211; Returns the <tt>Locale</tt>
instances for the current request. This method is inherited from the <tt>javax.servlet.ServletRequest</tt>
interface.</li>
	<li><tt>getResourceBundle(Locale)</tt> &#8211; Returns a <tt>ResourceBundle</tt>
for the given <tt>Locale</tt>. This method is specific to Sling.</li>
	<li><tt>getResourceBundle(String, Locale)</tt> &#8211; Returns a <tt>ResourceBundle</tt>
of a given base name for the given <tt>Locale</tt>. This method is specific to
Sling.</li>
</ul>



<p>These methods have a default implementation in the <tt>org.apache.sling.core</tt>
bundle and an extended and extensible implementation in the <tt>org.apache.sling.i18n</tt>
bundle.</p>


<h2><a name="InternationalizationSupport%28i18n%29-DefaultImplementationinthe%7B%7Borg.apache.sling.engine%7D%7DBundle"></a>Default
Implementation in the <tt>org.apache.sling.engine</tt> Bundle</h2>

<p>The default implementation of the above mentioned four methods in the Sling Engine
bundle is contained in the bundle-private class <tt>org.apache.sling.engine.impl.SlingHttpServletRequestImpl</tt>
which is the primary implementation of the <tt>SlingHttpServletRequest</tt> interface:</p>

<ul>
	<li><tt>getLocale()</tt> &#8211; Returns the <tt>Locale</tt>
from the request object of the servlet container in which Sling is running. As per the Servlet
API specification, this is either the primary Locale of the <tt>Accept-Language</tt>
request header or the server default locale.</li>
	<li><tt>getLocales()</tt> &#8211; Returns the <tt>Enumeration</tt>
from the request object of the servlet container in which Sling is running. As per the Servlet
API specification, this is either based on the <tt>Accept-Language</tt> request
header or just the server default locale.</li>
	<li><tt>getResourceBundle(Locale)</tt> &#8211; Returns a <tt>ResourceBundle</tt>
whose <tt>getString(String key)</tt> method returns the <tt>key</tt>
as the message and whose <tt>getKeys()</tt> method returns an empty <tt>Enumeration</tt>.</li>
	<li><tt>getResourceBundle(String, Locale)</tt> &#8211; Returns a <tt>ResourceBundle</tt>
whose <tt>getString(String key)</tt> method returns the <tt>key</tt>
as the message and whose <tt>getKeys()</tt> method returns an empty <tt>Enumeration</tt>.</li>
</ul>



<p>NOTE: Unlike the default implementations of the <tt>ResourceBundle</tt>
abstract class in the Java Runtime &#8211; <tt>PropertyResourceBundle</tt>
and <tt>ListResourceBundle</tt> &#8211; the <tt>ResourceBundle</tt>
returned by the default implementation of the <tt>getResourceBundle(Locale)</tt>
and <tt>getResourceBundle(String, Locale)</tt> always returns a string message
for any key, which is the key itself. This prevents throwing <tt>MissingResourceException</tt>.</p>



<h2><a name="InternationalizationSupport%28i18n%29-ExtensibleImplementationinthe%7B%7Borg.apache.sling.i18n%7D%7DBundle"></a>Extensible
Implementation in the <tt>org.apache.sling.i18n</tt> Bundle</h2>

<p>The <tt>org.apache.sling.i18n</tt> Bundle implements a request level
<tt>Filter</tt> providing extensible implementations of the above mentioned three
methods. Extensibility is attained by defining two service interfaces:</p>

<ul>
	<li><tt>LocaleResolver</tt> &#8211; The <tt>LocaleResolver</tt>
interface defines a method which may be implemented by a service outside of the sling.i18n
bundle. If no such service is registered the default behaviour is as described above for the
sling.core bundle. The service described by this interface is used to implement the <tt>getLocale()</tt>
and <tt>getLocales()</tt> method.</li>
</ul>


<ul>
	<li><tt>ResourceBundleProvider</tt> &#8211; The <tt>ResourceBundleProvider</tt>
interface defines two methods to acquire a <tt>ResourceBundle</tt> for any <tt>Locale</tt>
and an optional base name. This service interface is not intended to be implemented outside
of the sling.i18n bundle: A JCR Repository based implementation is contained in the sling.i18n
bundle. The <tt>ResourceBundleProvider</tt> service is not only used within the
sling.i18n bundle to implement the <tt>SlingHttpServletRequest.getResourceBundle(Locale)</tt>
and  <tt>SlingHttpServletRequest.getResourceBundle(String, Locale)</tt> methods.
The service may also be used by Sling applications to acquire <tt>ResourceBundle</tt>
instances without having a request object by getting the service and calling its <tt>getResourceBundle(Locale)</tt>
or <tt>getResourceBundle(String, Locale)</tt> method directly.</li>
</ul>




<h3><a name="InternationalizationSupport%28i18n%29-JCRRepositorybased%7B%7BResourceBundleProvider%7D%7D"></a>JCR
Repository based <tt>ResourceBundleProvider</tt></h3>

<p>The sling.i18n Bundle provides the implementation of the <tt>ResourceBundleProvider</tt>
interface, which may also be used outside of Sling requests for service tasks. This implementation
gets the messages from a JCR Repository stored below nodes of the mixin node type <tt>mix:language</tt>.
These language nodes have a <tt>jcr:language</tt> property naming the language
of the resources. In the context of the JCR based <tt>ResourceBundleProvider</tt>
this is of course expected to be the string value of respective <tt>Locale</tt>.</p>

<p>The (direct) child nodes of the <tt>mix:language</tt> node must contain
two special properties naming the key string and the message:</p>

<ul>
	<li><tt>sling:key</tt> &#8211; The <tt>sling:key</tt> property
is a string property being the key for which the node contains the message(s).</li>
	<li><tt>sling:message</tt> &#8211; The <tt>sling:message</tt>
property represents the resource for the key.</li>
</ul>


<p>The exact location of these nodes is not relevant as the <tt>ResourceBundleProvider</tt>
finds them by applying a JCR search. It is only required that the message nodes are located
below <tt>mix:language</tt> nodes. Such structures may also be scattered in the
repository to allow storing message resources next to where they are most likely used, such
as request scripts.</p>


<h3><a name="InternationalizationSupport%28i18n%29-%7B%7BResourceBundle%7D%7Dwithbasenames"></a><tt>ResourceBundle</tt>
with base names</h3>

<p>Similar to standard Java <tt>ResourceBundle</tt> instances, Sling <tt>ResourceBundle</tt>
instances may be created for base names through any of the <tt>getResourceBundle(String,
Locale)</tt> methods. These methods use the base name parameter as a selector for the
values of the <tt>sling:basename</tt> property of the <tt>mix:language</tt>
nodes.</p>

<p>The base name argument can take one three values:</p>

<table class='confluenceTable'><tbody>
<tr>
<th class='confluenceTh'> Value </th>
<th class='confluenceTh'> <tt>ResourceBundle</tt> selection </th>
</tr>
<tr>
<td class='confluenceTd'> <tt>null</tt> </td>
<td class='confluenceTd'> Selects messages of <tt>mix:language</tt> nodes
ignoring the existence or absence of <tt>sling:basename</tt> properties </td>
</tr>
<tr>
<td class='confluenceTd'> Empty String </td>
<td class='confluenceTd'> Selects messages of <tt>mix:language</tt> nodes
which have <tt>sling:basename</tt> properties, ignoring the actual values </td>
</tr>
<tr>
<td class='confluenceTd'> Any other Value </td>
<td class='confluenceTd'> Selects messages of <tt>mix:language</tt> nodes
whose <tt>sling:basename</tt> properties has any value which matches the base
name string </td>
</tr>
</tbody></table>

<p>The <tt>sling:basename</tt> property may be multi-valued, that is the
messages of a <tt>mix:language</tt> nodes may belong to multiple base names and
thus <tt>ResourceBundle</tt> instances.</p>


<h3><a name="InternationalizationSupport%28i18n%29-SampleResources"></a>Sample
Resources</h3>

<p>Consider the following repository content:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
   /libs/languages
           +-- English (nt:folder, mix:language)
           |    +-- jcr:language = en
           |    +-- m1 (sling:messageEntry)
           |    |    +-- sling:key = <span class="code-quote">"msg001"</span>
           |    |    +-- slign:message = <span class="code-quote">"This is a message"</span>
           |    +-- m2 (sling:messageEntry)
           |         +-- sling:key = <span class="code-quote">"msg002"</span>
           |         +-- slign:message = <span class="code-quote">"Another message"</span>
           +-- Deutsch (nt:folder, mix:language)
                +-- jcr:language = de
                +-- m1 (sling:messageEntry)
                |    +-- sling:key = <span class="code-quote">"msg001"</span>
                |    +-- slign:message = <span class="code-quote">"Das ist ein Text"</span>
                +-- m2 (sling:messageEntry)
                     +-- sling:key = <span class="code-quote">"msg002"</span>
                     +-- slign:message = <span class="code-quote">"Ein anderer Text"</span>

   /apps/myApp
           +-- English (nt:folder, mix:language)
           |    +-- jcr:language = en
           |    +-- mx (sling:messageEntry)
           |         +-- sling:key = <span class="code-quote">"msgXXX"</span>
           |         +-- slign:message = <span class="code-quote">"An Application Text"</span>
           +-- Deutsch (nt:folder, mix:language)
                +-- jcr:language = de
                +-- mx (sling:messageEntry)
                     +-- sling:key = <span class="code-quote">"msgXXX"</span>
                     +-- slign:message = <span class="code-quote">"Ein Anwendungstext"</span>
</pre>
</div></div>

<p>This content defines two languages <em>en</em> and <em>de</em>
with three messages <em>msg001</em>, <em>msg002</em> and <em>msgXXX</em>
each. The names of the respective nodes have no significance at all because all information
required is extracted from the <tt>jcr:language</tt>, <tt>sling:key</tt>
and <tt>sling:message</tt> properties.</p>


<h3><a name="InternationalizationSupport%28i18n%29-JCRNodeTypessupportingtheJCRRepositorybased%7B%7BResourceBundleProvider%7D%7D"></a>JCR
Node Types supporting the JCR Repository based <tt>ResourceBundleProvider</tt></h3>

<p>The sling.i18n bundle asserts the following node types:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>mix:language</b></div><div class="codeContent
panelContent">
<pre class="code-java">
[mix:language]
    mixin
  - jcr:language (string)
</pre>
</div></div>

<p>The <tt>mix:language</tt> mixin node type allows setting the <tt>jcr:language</tt>
property required by the <tt>ResourceBundleProvider</tt> implementation to identify
the message <tt>Locale</tt>.</p>



<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>sling:message and sling:messageEntry</b></div><div
class="codeContent panelContent">
<pre class="code-java">
[sling:message]
    mixin
  - sling:key (string)
  - sling:message (undefined)

[sling:messageEntry] &gt; nt:hierarchyNode, sling:message  
</pre>
</div></div>

<p>The <tt>sling:message</tt> and <tt>slign:messageEntry</tt>
are helper node types which may be used to create the nodes with the <tt>sling:key</tt>
and <tt>sling:message</tt> properties required by the <tt>ResourceBundleProvider</tt>.
The node types themselves are not required but by defining the required properties, they may
be of use.</p>
     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/SLINGxSITE/Internationalization+Support+%28i18n%29">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=80056&revisedVersion=6&originalVersion=5">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/SLINGxSITE/Internationalization+Support+%28i18n%29?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message