Minyaa is the successor of Kaamelot plugin, initially developped for JIRA 3.7 and maintained until JIRA 3.12.
When Minyaa started to replace Kaamelot, there were more than 120 modules in atlassian-plugin.xml file.
Kaamelot (now Minyaa) comes with improvements for different features in JIRA and many i18n properties.
Following Atlassian documentation, the way to define i18n properties is as follows :
<atlassian-plugin key="jira.plugin.minyaa.core" name="Minyaa JIRA Plugin Core" pluginsVersion="1">
<module key="ModuleKey" name="ModuleName" ...>
<resource type="i18n" name="i18n" location="com.myplugin.jira.MyClass" />
</module>
<module key="OtherModuleKey" name="OtherModuleName" ...>
<resource type="i18n" name="i18n" location="com.myplugin.jira.MySecondClass" />
</module>
</atlassian-plugin>
For some modules, the I18n resources were declared using 2 files, in order to reuse existing i18n resource files without having to duplicate translations.
<atlassian-plugin key="jira.plugin.minyaa.core" name="Minyaa JIRA Plugin Core" pluginsVersion="1">
<module key="ModuleKey" name="ModuleName" ...>
...
<resource type="i18n" name="i18n" location="com.myplugin.jira.MyClass" />
<resource type="i18n" name="i18n.Other" location="com.myplugin.jira.MyOtherClass" />
...
</module>
...
</atlassian-plugin>
Without more detailed documentation, when Kaamelot (Minyaa) required to extend existing i18n properties, the technic used was to append a new I18n Location in the extended WebWork Action, by accessing I18nBean object.
You can imagine that with 120 modules (components, webwork actions, Report, Portlet, Service, Issue Tab Panel, Project Tab Panel, …), extending i18n properties may be a pleasure …
With JIRA 4.0, the Gadgets arrived with new constraints … Minyaa portlets have been migrated into real Gadget (Atlassian Framework 2) only for JIRA 4.1.x.
As Minyaa performs many extensions in JIRA components, it was not possible to migrate Minyaa plugins in OSGi Plugin. Only Portlets have been migrated into Gadget in separate Plugin (jira-plugin-minyaa-xxx-gadgets-4.x.x-x.x.jar).
Gadgets, as any graphical item, require I18n Properties ! How does it work ?
Following Atlassian documentation, it only requires to declare in gadget xml file the supportedLocales macro with a key filter for I18n key. A new component (the I18nResolver) is able to load all I18n resources of all plugins and extend the Gadget definition using the key filter.
Ok, lets go ! For Minyaa Core, my first portlet to migrate was Minyaa Fragment Portlet …
- The Minyaa Core Gadget plugin (jira.plugin.minyaa.core.gadget) is created.
- The declaration is done as follows :
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs ...>
#supportedLocales("gadget.common,portlet.fragments")
</ModulePrefs>
...
</Module>
- All needed i18n resources definitions are provided by the plugin identified jira.plugin.minyaa.core
Oups … Some of i18n key were not translated!
After many search in documentation, I have connected the debugger in order to understand where the issue was …
Root cause :
The I18nResolver performs a scan of all i18n resources provided by different plugins, and jira.plugin.minyaa.core i18n resources are found and loaded!
Yes, but they are loaded in a Container based on HashMap and using the couple pluginKey + i18nName, as a key.
It means that jira.plugin.minyaa.core i18n resources are loaded using jira.plugin.minyaa.core as pluginKey, and each i18n Resources Name.
Since Minyaa Core plugin contains more than 1 module the i18n Resources were not unique.
Before the migration, the atlassian-plugin.xml modules were declared as follows :
<atlassian-plugin key="jira.plugin.minyaa.core" name="Minyaa JIRA Plugin Core" pluginsVersion="1">
<module key="ModuleKey" name="ModuleName" ...>
...
<resource type="i18n" name="i18n" location="com.myplugin.jira.MyClass" />
<resource type="i18n" name="i18nOther" location="com.myplugin.jira.MyOtherClass" />
...
</module>
<module key="OtherModuleKey" name="OtherModuleName" ...>
...
<resource type="i18n" name="i18n" location="com.myplugin.jira.MySecondClass" />
...
</module>
...
</atlassian-plugin>
Since the migration, each i18n resource has to be unique (per i18n resource file) as follows :
<atlassian-plugin key="jira.plugin.minyaa.core" name="Minyaa JIRA Plugin Core" pluginsVersion="1">
<module key="ModuleKey" name="ModuleName" ...>
...
<resource type="i18n" name="i18n" location="com.myplugin.jira.MyClass" />
<resource type="i18n" name="i18nOther" location="com.myplugin.jira.MyOtherClass" />
...
</module>
<module key="OtherModuleKey" name="OtherModuleName" ...>
...
<resource type="i18n" name="i18nSecond" location="com.myplugin.jira.MySecondClass" />
...
</module>
...
</atlassian-plugin>
I18n translation is important for all plugins, but you need to be aware that for large and old plugins, this is not a small work !