Developing and maintaining multi-language sites is a common problem for web developers. The usage of XML and XSLT makes this task easier, especially with Cocoon's content, logic and presentation separation concept.
Internationalization (i18n)
Process of developing a product in such a way that it works with data in different languages and can be adapted to various target markets without engineering changes.
Localization (l10n)
Subsequent process of translating and adapting a product to a given market's cultural conventions.
For more info on this see search here] or [http://www.google.com/search?hl=en&ie=ISO-8859-1&oe=ISO-8859-1&q=XML+Internationalization&btnG=Google+Search
This approach for internationalization (further - i18n) of applications within Cocoon is based on a transformer, which uses XML message catalogue for all the dictionary data and special markup for internationalized content.
The namespace of i18n markup in is defined as follows:
xmlns:i18n="http://apache.org/cocoon/i18n/2.0"
- for Cocoon 2.0.x versions
xmlns:i18n="http://apache.org/cocoon/i18n/2.1"
- Cocoon 2.1+ versions
The following features are supported by the i18n transformer:
This description supposes that you first defined a catalogue file like the following :
message.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <catalogue xml:lang="fr"> <message key="aKey">Une clé</message> ... <message key="zipcode">Code postal</message> </catalogue> |
You also must configure the main cocoon sitemap like this :
<map:transformers> <map:transformer name="i18n" src="org.apache.cocoon.transformation.I18nTransformer"> <catalogue-name>messages</catalogue-name> <catalogue-location>../../translations</catalogue-location> <cache-at-startup>true</cache-at-startup> </map:transformer> </map:transformers> |
Here is the way to call it in a pipeline :
<map:pipelines> <map:pipeline> <map:match pattern="mypage.html"> <map:generate src="mypage.html"/> <map:transform type="i18n"/> <map:serialize type="html"/> </map:match> </map:pipeline> </map:pipelines> |
Here is now how you can internationalize items :
Write <i18n:text>aKey</i18n:text>
in your HTML source code. This will be replaced by the text corresponding to this key in the catalogue.
If you want to use multiple catalogues, you can use this:
<map:transformers> <map:transformer name="i18n" src="org.apache.cocoon.transformation.I18nTransformer"> <catalogues default="other"> <catalogue id="other" name="OtherMessages" location="../../translations"/> <catalogue id="woody" name="WoodyMessages" location="../../translations"/> </catalogues> <cache-at-startup>true</cache-at-startup> </map:transformer> </map:transformers> |
Refer to the correct catalogue in your pipeline using the "default-catalogue-id" parameter:
<map:pipelines> <map:pipeline> <map:match pattern="mypage.html"> <map:generate src="mypage.html"/> <map:transform type="i18n"> <map:parameter name="default-catalogue-id" value="woody"/> </map:transform> <map:serialize type="html"/> </map:match> </map:pipeline> </map:pipelines> |
To be continued ...
if you get
java.lang.NullPointerException at org.apache.cocoon.components.ExtendedComponentSelector.release(ExtendedComponentSelector.java:317) at org.apache.cocoon.components.pipeline.AbstractProcessingPipeline.recycle(AbstractProcessingPipeline.java:639) at org.apache.cocoon.components.pipeline.impl.AbstractCachingProcessingPipeline.recycle(AbstractCachingProcessingPipeline.java:970) at org.apache.avalon.excalibur.pool.ResourceLimitingPool.put(ResourceLimitingPool.java:438) ... java.lang.IllegalStateException: You cannot lookup components on a disposed ComponentLocator at org.apache.avalon.excalibur.component.ExcaliburComponentManager.lookup(ExcaliburComponentManager.java:199) at org.apache.cocoon.components.CocoonComponentManager.lookup(CocoonComponentManager.java:315) ... |
for Cocoon 2.1, then make sure your namespace reads
xmlns:i18n="http://apache.org/cocoon/i18n/2.1" |
instead of "2.0"...
---Tom Eicher