Author: kwin
Date: Wed Jun 17 12:16:12 2015
New Revision: 1685996
URL: http://svn.apache.org/r1685996
Log:
SLING-4543 add documentation of the JSON based format
also clean up documentation and fix some typos (related to node types)
Modified:
sling/site/trunk/content/documentation/bundles/internationalization-support-i18n.mdtext
Modified:
sling/site/trunk/content/documentation/bundles/internationalization-support-i18n.mdtext
URL:
http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/bundles/internationalization-support-i18n.mdtext?rev=1685996&r1=1685995&r2=1685996&view=diff
==============================================================================
---
sling/site/trunk/content/documentation/bundles/internationalization-support-i18n.mdtext
(original)
+++
sling/site/trunk/content/documentation/bundles/internationalization-support-i18n.mdtext
Wed Jun 17 12:16:12 2015
@@ -37,71 +37,80 @@ The `org.apache.sling.i18n` Bundle imple
### JCR Repository based `ResourceBundleProvider`
-The sling.i18n Bundle provides the implementation of the
`ResourceBundleProvider` 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 `mix:language`. These
language nodes have a `jcr:language` property naming the language of the
resources. In the context of the JCR based `ResourceBundleProvider` this is of
course expected to be the string value of respective `Locale`.
+The sling.i18n Bundle provides the implementation of the
`ResourceBundleProvider` 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 `mix:language`. These
language nodes have a `jcr:language` property naming the language of the
resources. In the context of the JCR based `ResourceBundleProvider` this is of
course expected to be the string value of respective `Locale`. The format may
either be the format as described in
[Locale.toString](http://docs.oracle.com/javase/7/docs/api/java/util/Locale.html#toString%28%29)
or as described in [RFC4646](https://www.ietf.org/rfc/rfc4646.txt) (both
formats are also accepted in lower-case).
-The (direct) child nodes of the `mix:language` node must have the
`jcr:primaryType` set to `sling:MessageEntry` and must contain two special
properties naming the key string and the message:
-
- * `sling:key` -- The `sling:key` property is a string property being the
key for which the node contains the message(s).
- * `sling:message` -- The `sling:message` property represents the resource
for the key.
-
-The exact location of these nodes is not relevant as the
`ResourceBundleProvider` finds them by applying a JCR search. It is only
required that the message nodes are located below `mix:language` 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.
+The exact location of these nodes is not relevant as the
`ResourceBundleProvider` finds them by applying a JCR search.
+Two different types of storage formats are supported for the individual
dictionaries
-### `ResourceBundle` with base names
-
-Similar to standard Java `ResourceBundle` instances, Sling `ResourceBundle`
instances may be created for base names through any of the
`getResourceBundle(String, Locale)` methods. These methods use the base name
parameter as a selector for the values of the `sling:basename` property of the
`mix:language` nodes.
+#### `sling:MessageEntry` based
-The base name argument can take one three values:
-
-| Value | `ResourceBundle` selection |
-|--|--|
-| `null` | Selects messages of `mix:language` nodes ignoring the existence or
absence of `sling:basename` properties |
-| Empty String | Selects messages of `mix:language` nodes which have
`sling:basename` properties, ignoring the actual values |
-| Any other Value | Selects messages of `mix:language` nodes whose
`sling:basename` properties has any value which matches the base name string |
-
-The `sling:basename` property may be multi-valued, that is the messages of a
`mix:language` nodes may belong to multiple base names and thus
`ResourceBundle` instances.
+The (direct) child nodes of the `mix:language` node must have the
`jcr:primaryType` set to `sling:MessageEntry` and must contain two special
properties naming the key string and the message:
+ * `sling:key` -- The `sling:key` property is a string property being the
key for which the node contains the message(s). This property is optional. If
it is not set the key is determined by the resource name of the parent
`sling:messageEntry`.
+ * `sling:message` -- The `sling:message` property represents the resource
for the key.
-### Sample Resources
+It is only required that the message nodes are located below `mix:language`
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.
-Consider the following repository content:
+##### Sample Resources
+Content for dictionaries in this format might look like this:
/libs/languages
+-- English (nt:folder, mix:language)
| +-- jcr:language = en
- | +-- m1 (sling:messageEntry)
+ | +-- m1 (sling:MessageEntry)
| | +-- sling:key = "msg001"
- | | +-- slign:message = "This is a message"
- | +-- m2 (sling:messageEntry)
+ | | +-- sling:message = "This is a message"
+ | +-- m2 (sling:MessageEntry)
| +-- sling:key = "msg002"
- | +-- slign:message = "Another message"
+ | +-- sling:message = "Another message"
+-- Deutsch (nt:folder, mix:language)
+-- jcr:language = de
- +-- m1 (sling:messageEntry)
+ +-- m1 (sling:MessageEntry)
| +-- sling:key = "msg001"
- | +-- slign:message = "Das ist ein Text"
- +-- m2 (sling:messageEntry)
+ | +-- sling:message = "Das ist ein Text"
+ +-- m2 (sling:MessageEntry)
+-- sling:key = "msg002"
- +-- slign:message = "Ein anderer Text"
+ +-- sling:message = "Ein anderer Text"
/apps/myApp
+-- English (nt:folder, mix:language)
| +-- jcr:language = en
- | +-- mx (sling:messageEntry)
+ | +-- mx (sling:MessageEntry)
| +-- sling:key = "msgXXX"
- | +-- slign:message = "An Application Text"
+ | +-- sling:message = "An Application Text"
+-- Deutsch (nt:folder, mix:language)
+-- jcr:language = de
- +-- mx (sling:messageEntry)
+ +-- mx (sling:MessageEntry)
+-- sling:key = "msgXXX"
- +-- slign:message = "Ein Anwendungstext"
+ +-- sling:message = "Ein Anwendungstext"
+
+This content defines two languages *en* and *de* with three messages *msg001*,
*msg002* and *msgXXX* each. The names of the respective resources have no
significance (in case the `sling:key` is set).
+#### JSON-file based
-This content defines two languages *en* and *de* with three messages *msg001*,
*msg002* and *msgXXX* each. The names of the respective nodes have no
significance at all because all information required is extracted from the
`jcr:language`, `sling:key` and `sling:message` properties.
+Since Version 2.4.2 the i18n bundle supports dictionaries in JSON-format
([SLING-4543](https://issues.apache.org/jira/browse/SLING-4543)).
+Since loading such dictionaries is much faster than loading the ones based on
`sling:MessageEntry`s this format should be used preferably.
+This format is assumed if the `mix:language` resource name is ending with the
extension `.json`.
+The parser will take any "key":"value" pair in the JSON file, including those
in nested objects or arrays. Normally, a dictionary will be just a single json
object = hash map though.
+
+##### Sample Resources
+
+Content for this format might look like this:
+
+ /libs/languages
+ +-- english.json (nt:file, mix:language)
+ | +-- jcr:language = en
+ | +-- jcr:content (nt:resource)
+ | + jcr:data (containing the actual JSON file)
+ +-- deutsch.json (nt:file, mix:language)
+ +-- jcr:language = de
+ +-- jcr:content (nt:resource)
+ + jcr:data (containing the actual JSON file)
-### JCR Node Types supporting the JCR Repository based `ResourceBundleProvider`
+#### JCR Node Types supporting the JCR Repository based
`ResourceBundleProvider`
The sling.i18n bundle asserts the following node types:
@@ -112,8 +121,6 @@ The sling.i18n bundle asserts the follow
The `mix:language` mixin node type allows setting the `jcr:language` property
required by the `ResourceBundleProvider` implementation to identify the message
`Locale`.
-
-
[sling:Message]
mixin
- sling:key (string)
@@ -122,4 +129,45 @@ The `mix:language` mixin node type allow
[sling:MessageEntry] > nt:hierarchyNode, sling:Message
-The `sling:Message` and `slign:MessageEntry` are helper node types which may
be used to create the nodes with the `sling:key` and `sling:message` properties
required by the `ResourceBundleProvider`. The node types themselves are not
required but by defining the required properties, they may be of use.
+The `sling:Message` and `sling:MessageEntry` are helper node types. The latter
must be used to create the nodes for the `sling:MessageEntry` based format.
+
+### `ResourceBundle` with base names
+
+Similar to standard Java `ResourceBundle` instances, Sling `ResourceBundle`
instances may be created for base names through any of the
`getResourceBundle(String, Locale)` methods. These methods use the base name
parameter as a selector for the values of the `sling:basename` property of the
`mix:language` nodes.
+
+The base name argument can take one three values:
+
+| Value | `ResourceBundle` selection |
+|--|--|
+| `null` | Selects messages of `mix:language` nodes ignoring the existence or
absence of `sling:basename` properties |
+| Empty String | Selects messages of `mix:language` nodes which have
`sling:basename` properties, ignoring the actual values |
+| Any other Value | Selects messages of `mix:language` nodes whose
`sling:basename` properties has any value which matches the base name string |
+
+The `sling:basename` property may be multi-valued, that is the messages of a
`mix:language` nodes may belong to multiple base names and thus
`ResourceBundle` instances.
+
+### `ResourceBundle` hierarchies
+The dictionary entries for one `JcrResourceBundle` are always ordered like the
resource resolver search paths, so usually
+
+ 1. dictionary entries below `/apps`
+ 2. dictionary entries below `/libs`
+ 3. dictionary entries anywhere else (outside the search path)
+
+That means that the message for the same key in `/apps` overwrites the one in
`/libs` (if both are for the same locale and base name). Within those
categories the order is non-deterministic, so if there are two entries for the
same key in `/apps/...` (for the same locale and base name), any entry may be
used.
+
+The resource bundles of the same base name with different locales also form a
hierarchy. Each key is looked up recursively first in the ResourceBundle itself
and then within its parent ResourceBundle. The parent resource bundle is the
one having the same base name and the parent locale.
+
+The locale hierarchy is ordered like this:
+
+1. `<Language> <Country> <Variant> `
+2. `<Language> <Country>`
+3. `<Language>`
+4. `<Default Locale>`, usually `en`
+
+So for the locale `de-DE-MAC` the fallback order would be
+
+1. `de-DE-MAC`
+2. `de-DE`
+3. `de`
+4. `en`
+
+The last resort (root resource bundle in all hierarchies) is always the bundle
which returns the requested key as the value.
\ No newline at end of file