-
Notifications
You must be signed in to change notification settings - Fork 10
Internationalization: Working with i18n
The xCoLab can support several languages when enabled. This feature and the documentation are still under development - stay tuned for updates!
Not every CoLab needs to support i18n, so there is a feature flag to control whether i18n is available. By default, the i18n feature is disabled.
To enable it, set the ConfigurationAttribute IS_I18N_ACTIVE to true (or set it to false if you want to disable i18n).
Many of the XCoLab configuration parameters are stored in the database table admin__configuration_attribute. This table has a "name" field which matches the name of the attribute, and "numeric_value", "string_value" and "real_value" fields to hold the value of the parameter, depending on its data type.
If an attribute is not present in this table, it will use the default value. For i18n, this is the case by default, so to enable it the first time you can execute the following SQL sentence:
INSERT INTO admin__configuration_attribute (name, additional_id, numeric_value) VALUES ('IS_I18N_ACTIVE', 0, 1);
Once the register exists, you can deactivate it again either by deleting the register or toggling the boolean value as in:
UPDATE admin__configuration_attribute SET numeric_value = 0 WHERE name = 'IS_I18N_ACTIVE';
The user's language is determined as follows:
- If a member is logged in, this member's preferred locale is used.
- If there is a preferred locale set in the browser's session, it is used.
- Otherwise, the default locale (en_US) is used.
A visitor can change this preference by using either the language dropdown in the menu bar on the top of the screen, or in the footer. This automatically stores the new preference in the browser's session and, if they are logged in, in their profile.
There are several places that contain translations.
Most translations are contained in so-called properties files, which are key-value pairs of the format key=value. You can find all the i18n files in the i18n folder. There is one letter for each language, identified by its 2 letter ISO 639-1 code.
There are also some translations of system elements. Currently, these have to be done directly in the database tables, as they are usually basic configuration elements.
Some admin content, such as contests, can have translations configured through the editing tools in the platform. For contests, just go to the translations tab and translate the English title and descriptions into the desired languages.
To support internationalization, messages that are shown to the user should not be hard-coded. They must have the possibility to be automatically translated to other languages, so a placeholder for the message is required. The Spring Framework JSP Tag Library offers such a placeholder through its message
JSP tag, documented here.
As an example, let's suppose we want to display the text of a 'reply' button. If the application was only in English, the code would be similar to the following:
<button type="button" class="btn btn-primary">
Reply
</button>
However, this button always displays the text 'Reply' in English, even if the instance is configured in another language. Using the message
helper tag, the correct code would be:
<button type="button" class="btn btn-primary">
<spring:message code="message.reply.button"/>
</button>
It is necessary to define the key-value pair for the specific "message.reply.button" key in the "message.properties" file. The keys use namespacing, so the first word of the key can be used to identify its definition file. In our example, the file "message.properties" contains:
message.reply.button = Reply
And every translation file has the equivalent definition in the corresponding language, like in "message_es.properties":
message.reply.button = Responder
Sometimes the message to be displayed requires content that is only available at runtime. For such cases, the "properties" files support variable substitution through positional arguments. They can be defined with curly brackets surrounding the argument position, counting from 0. For instance:
message.from.message=Message from {0} to {1}
The arguments can be passed from the view using the same helper, with the arguments
and argumentSeparator
attributes:
<spring:message code="message.from.message" arguments="${currentMessageBean.from.displayName},${currentMessageBean.to.get(0).displayName}" argumentSeparator=","/>