Message Bundles
The most common task of localization is to provide messages depending on the current user locale. To achieve this, messages must be extracted from code and placed in special property files, one file per language. A collection of such files is called a message bundle.
Apart from messages, the message bundle can also contain localized data format strings.
The default message bundle of your project is a set of messages_<language>.properties
files located in the base package under the src/main/resources
folder.
Message bundle files must have the UTF-8 encoding. |
Setting Up Locales
When you create a new project using Studio, you can set up the list of supported locales in the Locales field of the project wizard. This field allows you to select a language code and set its name.
Studio writes the list of language codes to the jmix.core.availableLocales
application property and language names to the corresponding messages_<language>.properties
files with localeDisplayName.<language>
key. You can later edit these properties manually or use the Locales tab of the Project Properties window in Studio.
For example, if you have defined two languages for your application: en
- English
and ru
- Русский
, you have the following file structure in the project (provided that the base package is localization_demo.ex1
):
src/
main/
resources/
localization_demo/
ex1/
messages_en.properties
messages_ru.properties
application.properties
And the files have the following contents:
localeDisplayName.en = English
localeDisplayName.ru = Русский
jmix.core.availableLocales = en,ru
Creating Messages
Group and Key
Usually, an application contains a single message bundle. Because the number of messages even in a simple application can be quite large, we recommend making property keys of two parts: the group and the message key, separated by the forward slash (/
). It allows you to group related messages and avoid naming conflicts. In the following example, localization_demo.ex1.screen.main
is the group and application.caption
is the message key:
localization_demo.ex1.screen.main/application.caption = Sample application
But you can also define a message without a group, for example:
messageWithoutGroup = Message without a group
Localizing Data Model
Jmix introduces some conventions on localization of the data model elements: entity and attribute names, enumeration values. It allows the framework to find the localized names when displaying entities and enumerations in UI components.
Entity name is localized using the <package>/<class>
format, attribute name - using the <package>/<class>.<attribute>
format. For example:
# entity name
localization_demo.ex1.entity/Customer = Customer
# attribute names
localization_demo.ex1.entity/Customer.id = Id
localization_demo.ex1.entity/Customer.version = Version
localization_demo.ex1.entity/Customer.name = Name
Enumeration name is localized using the <package>/<class>
format, enumeration value - using the <package>/<class>.<value>
format. For example:
# enumeration name
localization_demo.ex1.entity/Status = Status
# enumeration values
localization_demo.ex1.entity/Status.ACTIVE = Active
localization_demo.ex1.entity/Status.SUSPENDED = Suspended
localization_demo.ex1.entity/Status.INACTIVE = Inactive
You can easily create localized names of the data model elements in Studio visual designers. Click the 🌐 (globe) button next to the element name and enter localized values for available locales in the Localized Message dialog. |
Additional Bundles
In a big application with a lot of messages you can maintain a reasonable size of the property files by defining additional message bundles:
-
Create a set of property files with arbitrary name in any directory under
src/main/resources
. In the example below, we createdadditional_messages
files in the same base package as the main message bundle:src/ main/ resources/ localization_demo/ ex1/ additional_messages_en.properties additional_messages_ru.properties messages_en.properties messages_ru.properties
-
Write localized messages in the additional files in the same way as in the main bundle.
-
Add the
@MessageSourceBasenames
annotation to the application class and set the path and name of the additional bundle in it:@SpringBootApplication @MessageSourceBasenames({"localization_demo/ex1/additional_messages"}) public class LocalizationExampleApplication {
Messages from all bundles of the application are loaded into a single list, so property keys must be unique among all your bundles. |
Using Messages
In Java Code
To get localized messages from the message bundle, use the Messages
bean. The most common use case is to invoke its getMessage()
method and provide the message group and key. The method will return a message for the current user locale, or the given message key if the message is not found.
In the following example, we define a message in a message bundle and get it using different methods of the Messages
bean:
localization_demo.ex1/someNotification = Something has happened
String message1 = messages.getMessage("localization_demo.ex1/someNotification"); (1)
String message2 = messages.getMessage("localization_demo.ex1", "someNotification"); (2)
String message3 = messages.getMessage(getClass(), "someNotification"); (3)
All three methods return the same value: Something has happened
.
1 | The whole property key is specified. |
2 | The group and the message key are specified separately. |
3 | If the first argument is Class , the method uses the package of the class as the group. |
There is also an overloaded getMessage()
method accepting Enum
. Use it to retrieve a localized enum value, for example:
String message = messages.getMessage(Status.ACTIVE);
In Backoffice UI Screens
Backoffice UI screen descriptors and menu configuration files recognize the msg://
prefix in messages and load such messages from the message bundle.
Let’s consider different options of using msg://
with examples.
-
The group of the message is inferred from the screen’s package.
For example, if you have defined a message with
localization_demo.ex1.screen.user
group:messages_en.propertieslocalization_demo.ex1.screen.user/someMessage = Some message
you can retrieve it in a screen descriptor located in the
localization_demo.ex1.screen.user
package simply by specifying the message key without the group:localization_demo/ex1/screen/user/user-browse.xml<label value="msg://someMessage"/>
-
Getting a message with an arbitrary group.
You can retrieve the message from the previous example in any screen by specifying both the group and the key after the
msg://
prefix, for example:localization_demo/ex1/screen/main/main-screen.xml<label value="msg://localization_demo.ex1.screen.user/someMessage"/>
-
Getting a message without a group.
To retrieve a message without a group, use triple slash in the prefix
msg:///
, followed by the message key.For example, if you have defined a message like this:
messageWithoutGroup = Message without a group
you can get it in any screen descriptor as follows:
<label value="msg:///messageWithoutGroup"/>