We saw in earlier chapters how to write webwork plugins to create new or extended JIRA actions. In this recipe, we will see how we can personalize the messages in these plugins using internationalization and localization.
As Wikipedia puts it:
"Internationalization and localization are means of adapting computer software to different languages, regional differences and technical requirements of a target market. Internationalization is the process of designing a software application so that it can be adapted to various languages and regions without engineering changes. Localization is the process of adapting internationalized software for a specific region or language by adding locale-specific components and translating text."
The terms internationalization and localization are abbreviated to i18n, where 18 stands for the number of letters between the first i and the last n in internationalization!
Internationalization in a webwork plugin is achieved with the help of a resource bundle defined in the atlassian-plugin.xml file
. Following are the steps required to enable it in a JIRA webwork plugin:
resource
definition in the atlassian-plugin.xml
file.<resource type="i18n" name="i18n" location="jtricks-utilities"/>
Here, the type of the resource is i18n,
and we have defined the location as j-tricks-utilities
. The location
is the location of the property file, ending with the file name, and this will be used for adding the key/value pairs required for the translation. This location is the relative path to the src/main/resources
folder, and we should specify the full path in this attribute if the property file is added in a different folder.
welcome.demo.heading=English welcome.demo.message=Welcome to the demo
Here, welcome.demo.heading
is the key that will be used and will be the same across all language property files. The value here, "English", will be used for the default locale but will have equivalent translations in the other language property files.
${fileName}_${languageCode}_${countryCode}.properties
. For example, if we need to personalize the above action for French users, the following will be the property filename:jtricks-utilities _fr_FR.properties
welcome.demo.heading
in each of the property files with the appropriate translation as the values. For example, a property with the value "English
" in the default property file will have the value "Français
" in French!In our example, following is how the jtricks-utilities _fr_FR.properties
will look.
welcome.demo.heading=Français welcome.demo.message=Bienvenue sur la demo
As you can see, the key is the same but the values are the respective translations.
With that, the plugin is ready for translation and we can use the i18n keys in the action class and velocity templates.
In velocity templates, using 18n is really easy. All you have to do is use the i18n
variable, which is already available in the velocity context. This variable is of type com.atlassian.jira.util.I18nHelper
class and exposes the getText
method, which can be used as follows:
$i18n.getText("welcome.demo.heading")
In the action class, we can retrieve the same I18nHelper
class using the getI18nHelper()
method, but let us also see how it can be injected in the constructor, just in case you want to do the same in other plugin modules.
public class TranslateAction extends JiraWebActionSupport { private final I18nHelper i18nHelper; public TranslateAction(I18nHelper i18nHelper) { super(); this.i18nHelper = i18nHelper; } }
Once the helper class is initialized, it can be used anywhere in the action class. For example, the translated value can be printed as follows:
System.out.println("Translated text:" + this.i18nHelper.getText("welcome.demo.message"));
You can also retrieve the I18nHelper
for a specific locale using the I18nHelper.BeanFactory
class.
I18nHelper frenchI18nHelper =i18nBeanFactory.getInstance(Locale.FRANCE);
Let us say we have used the above i18n
resources in our webwork action class. A sample velocity template used in the input
view will look like the following.
<html> <head> <meta name="decorator" content="atl.general"/> <title>$i18n.getText("welcome.demo.heading")</title> </head> <body class="aui-page-focused aui-page-size-large"> <div id="page"> <section id="content" role="main"> <div class="aui-page-panel"> <div class="aui-page-panel-inner"> <section class="aui-page-panel-content"> <h2>$i18n.getText("welcome.demo.heading")</h2> <p>$i18n.getText("welcome.demo.message")</p> </section> </div> </div> </section> </div> </body> </html>
When the action is invoked, a user with the English locale will see the following:
The same page is shown to a user with a French locale, as shown below.
3.147.53.166