Skip to content
OpenCms documentation
OpenCms documentation

Message bundles

Localization and internationalization is an important topic when maintaining multilingual websites. OpenCms has a variety of mechanisms to support multilingual websites, as well as the localization of the OpenCms grapical user interface. A central part of these mechanisms are so called message or resource bundles. They are the default Java mechanism for the internationalization. In the raw version of those bundles, one provides for each language a so called property file, containing key-value pairs with message identifiers as keys and localized messages as values. OpenCms supports the raw Java bundles, but also provides two slightly refined versions of that mechanism to ease the handling.

In this topic we discuss for what purposes message bundles are used in OpenCms. Furthermore, we provide an overview on the three alternative ways of defining message bundles and discuss the special behavior of so called "workplace" bundles.

Since version 10.5 OpenCms features a special editor for message bundles and a descriptor mechanism for bundles, that allows the fix the key set for a bundle and provide extra information for each key. We take a look at these features.

To adjust the user interface or the output of a website, it is often the case that messages have to be localized. One the one hand, that means to translate words or sentences. On the other hand that means to translate also date and number formatting, etc. Java has a mechanism for such localization. In particular for the localization of messages: so called resource or message bundles. They can be backed up with property files, which is the way we use them in OpenCms. Each such properties file contains the key-value pairs. Keys are identifiers of messages. Values are localized messages.

Let's give a little "Hello World" example with English and German localization. English should serve as default language, if the requested localization is missing. To get a localized "Hello world", we need a key for the message, let's say hello.world. Then we need an English and a German properties file that contains the key. The English file we name hello.properties and it's content is:

hello.world = Hello world!

The German properties file we name hello_de.properties and it's content is:

hello.world = Hallo Welt!

We could add more language version, e.g., hello_fr.properties for French. You may have noted that for the English version we did not add _en to the file name. Omitting the locale specification makes this file the default localization. When, for example in our setting, we ask for the Spanish localization of hello.world, then we get "Hello world!", because the file with hello_es.properties is missing, and thus hello.properties is used.

To glue the properties files together to a resource bundle, all of them have to be placed in the same folder that is accessible for the servlet container. If we consider a setting with a servlet container as for OpenCms. Typically, all are placed below the folder {webapp home}/WEB-INF/classes/. The subfolder structure below the classes/ together with the name of the properties files specify the resource bundle's name. For example, if we place our hello_{locale}.properties files in the folder my/demo/bundle/, they make up the resource bundle my.demo.bundle.hello.

We can now access the bundle my.demo.bundle.hello for example a JSP using the <fmt:>-taglib from the JSTL. To print out a localized "Hello world!" (or "Hallo Welt!"), we could write the following JSP.

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<fmt:setLocale value="en" /> <%-- replace "en" with "de" for the German version --%>
<fmt:bundle basename="my.demo.bundle.hello">
  <fmt:message key="hello.world" />
</fmt:bundle>

The use of resource bundles is not limited to JSPs. They can also be used in normal Java code. Moreover, in OpenCms resource bundles are used heavily for interface localization. The example given here is also quite simple. The messages can also have place holders and allow even more advanced features. Please ask Google for more information.

Resource bundles are used for all localized messages in OpenCms. In particular, one can distinguish four different main applications:

  1. Localization of the workplace and system dialogs (read about this here)
  2. Localization of the content specific parts of dialogs (read about the special workplace bundles and see how localization works here)
  3. Localization of the content editor for a specific resource type (display names and descriptions for resource types, etc. - see how it works here)
  4. Localization in JSPs (e.g., of the output of formatters, template or dynamic functions)

How to precisely perform the localization cases 1. to 3. is described in the topic about the localization of menus, see here. To understand the descriptions you need some background on message bundles as discussed below. For case 4, you just need the example above and additionally you should read about the tag <cms:bundle> when you use the OpenCms specific options for providing resource bundles.

In OpenCms resource bundles are typically added via modules. Where to place the bundles inside the modules depends on which technique for bundles you use.

We encourage you to use of property resource bundles - optionally with bundle descriptors.
We are not talking about the bundles for workplace and (resource type independent) system dialog localization here. See here for some description about such bundles. In this section we are concerned about the bundles for content specific localization of editors and website localization.

You can use properties files to back up resource bundles as explained in section "About resource bundles". If doing so, you typically place the properties files of the bundles in the classes/ subfolder of your module's main folder and set an export point from that folder to {webapp home}/WEB-INF/classes/. As folder structure for the bundles, you typically use the module name, i.e., /my/demo/bundles/ for the module my.demo.bundles. The properties files have just type "Text file" (plain) and the bundle name is build from the folder and file names as described in Section "About resource bundles".

The big drawback of using the default mechanism is that you always have to restart your servlet container until changes in the properties files are recognized.

Files of the type property resource bundle (propertyvfsbundle) contain key-value pairs exactly as the files from the approach in section "Using the default properties files". The main difference is that they are loaded differently to overcome the problem of restarting the servlet container to promote changes in the files.

Also where you put and how you name the property resource bundle files is different from where you put the properties files for the default Java mechanism. Using property resource bundles, the files are named as bundle's base name + (optional) _{locale} extension. By convention:

  • The property resouce bundles are placed in the modules i18n/-subfolder.
  • The basename is {module name}.{bundle specific name}.

As example, consider that we want properties files as in section "About resource bundles". We place them in the module my.demo.bundle and thus in the VFS folder /system/modules/my.demo.bundle/i18n/. The files are added via the workplace ("New" -> "Configurations" -> "Property resource bundle") and named

  • my.demo.bundle.test_en
  • my.demo.bundle.test_de

They are used in a JSP as described in section "About resource bundles", except that the tag <fmt:bundle> has to be replaced with <cms:bundle>.

The advantage of using property resource bundles is, that it suffices to publish the bundles files to make changes available. Restarting the servlet container is not required.
We strongly recommend to place all files of one bundle in the same folder. Not doing so, the bundle editor will fail to correctly switch between the different translations.
The translation for the system's default locale (in the default installation "en") is automatically used as default translation. I.e., you do not need to add a file without locale postfix containing the default translation. Actually, you should not even do so. Because you should not, we also prohibit editing such file via the bundle editor.
We recommend to use property resource bundles instead of XML resource bundles. XML resource bundles are deprecated since the bundle editor was added in OpenCms 10.5.

The ways to state key-value pairs so far are both based on maintaining language specific text files with a key-value pair at each line. OpenCms additionally offers an option to store the key-value pairs for all languages in a single file that is editabe via the form-based content editor. Such files are called XML resource bundles (xmlvfsbundle). They are typically added in the i18n/ folder of the module they are shipped with and named {module name}.{bundle specific name}.

As example, consider that we want an equivalent to the properties files described in section "About resource bundles". Therefor, we place the XML resource bundle in the module my.demo.bundle and thus in the VFS folder /system/modules/my.demo.bundle/i18n/. The bundle is added via the workplace ("New" -> "Other options" -> "XML resource bundle") and named

  • my.demo.bundle.test

The bundle can be used in a JSP as described in section "About resource bundles", except that the tag <fmt:bundle> has to be replaced with <cms:bundle>.

The advantage of using XML resource bundles is, that it suffices to publish the bundles files to make changes available. Restarting the servlet container is not required.

In contrast to property resource bundles, the XML resource bundles allow to edit the key-value pairs via the content editor and they also allow to keep all localizations in one file. If this is an advantage or not depends on your usecase.

At some places where localization takes place, you cannot explicitely state which resource bundle you use. This is in particular the case, when the available content types and their descriptions are listed in the "Add wizard" of the page editor. The keys used for localization here have to follow a specific name scheme (see here for details) and also reside in so called workplace bundles.

A workplace bundle is a bundle that either follows the one of the name schemes

  • {module name}.workplace
  • {module name}.messages

or is referenced as "Localization" in a content element configuration in the module configuration.

When the workplace is build, all bundles following that name scheme are collected and merged into a single bundle that is present globally without opening it explicitely. Hence, what you should be aware of:

  • workplace bundles should have very unique keys
  • workplace bundles typically contain only the keys that are used where you can not explicitely access another bundle.

Which of the techniques for writing properties files you use for workplace bundles is your choice. The only thing you should know additionally:

To make changes in workplace bundles visible, the workplace has to be rebuild. ("Administration View" -> "Workplace Tools" -> "Re-Initialize the Workplace").
Be aware of the special role and naming scheme for workplace bundles to not accidentically make your "normal" bundle a workplace bundle.

Bundle descriptors are added in OpenCms 10.5. They are unilingual contents of type "Bundle descriptor" (bundledescriptor). They play together with the bundle editor. In a bundle descriptor you can:

  • fix the key set of a bundle (shown in and stored by the bundle editor),
  • add two pieces of extra information for each key (description and default value if not configured differently).

Each bundle descriptor describes exactly one bundle and must be named

  • {bundle name}_desc

The descriptor does not necessarily have to reside in the same folder as the other bundle files. In general, it is beneficial to grant write access to the descriptor only for users that should change the key set of a bundle, e.g., for template developers. This way, the editors that translate messages can not change the key set when they edit a message bundle via the bundle editor.

Have a look at the description of the bundle editor, to see how it deals with bundle descriptors.

Be aware the the bundle descriptor has only influence on the bundle editor. So it does not prevent users from making arbitrary changes to message bundles by editing the source code directly.