This page gives guidelines to I18n for:

Principles

Although the basics of the i18n mechanism are the same for every part of the ecosystem, the packaging differs depending on what you are developing:

  • Sonar Platform and Sonar Community Plugins rely on Language Pack plugins to get translations
  • Other independant Sonar plugins embed by themselves all the translations they need

Translation bundles

There are two types of files for localized messages:

Properties files

HTML files

In the Java API, properties files are supposed to be encoded in ISO-8859 charset. Without good tooling, this can be quite annoying to write translation for languages that do not fit in this charset.
This is why we deciced to encode the properties files in UTF-8, and let Maven turn them into ASCII at build time thanks to native2ascii-maven-plugin (check the French plugin pom.xml). This makes the process of writing translations with a standard editor far easier.
HTML files must also be encoded in UTF-8.

Naming conventions for keys

Here are the conventions you have to know about keys :

Key

Description

Example

metric.<key>.name

Metric name

metric.ncloc.name=Lines of code

metric.<key>.description

Metric description

metric.ncloc.description=Non Commenting Lines of Code

notification.channel.<channel key>

Name of notification channel

notification.channel.EmailNotificationChannel=Email

notification.dispatcher.<dispatcher key>

Subscription to notification channel

notification.dispatcher.ChangesInReviewAssignedToMeOrCreatedByMe=Changes in review assigned to me or created by me

rule.<repository>.<key>.name

Rule name

rule.pmd.StringInstantiation.name=String Instantiation

rule.<repository>.<key>.param.<param key>

Description of rule parameter

rule.pmd.VariableNamingConventions.param.memberSuffix=Suffix for member variables

dashboard.<key>.nameDashboard name, since 2.14.dashboard.Hotstpots.name=Point Chauds

qualifier.<key>

qualifiers.<key>

Qualifier name, since 2.13.

qualifier.TRK=Project

qualifiers.TRK=Projects

widget.<key>.name

Widget name

widget.alerts.name=Alerts

widget.<key>.description

Widget description

widget.alerts.description=Display project alerts

widget.<key>.param.<property key>

Description of widget property

widget.alerts.param.threshold=Threshold

widget.<key>.*

Any other widget message

widget.alerts.tooltip=Threshold is raised

<page key>.page

Page names shown in the left sidebar

cloud.page=Cloud

<page key>.*

Any other keys used in a page

cloud.size=Size

property.category.*

Category name of properties, since 2.11

property.category.General=Général

property.<key>.name

Property name, since 2.11

property.sonar.sourceEncoding.name=Source encoding

property.<key>.description

Property description, since 2.11

property.sonar.sourceEncoding.description=Source encoding

<plugin key>.*

Any other keys used by plugin

 

How to use localized messages ?

Ruby on Rails API

This API is used when implementing Ruby widgets or pages. It's really simple, a single method must be used :

message(property_key, options={})

Options are :

Examples :

message('cloud.size')
message('cloud.size', :default => 'Cloud')
message('with.arguments', :params => ['First', 'Two'])
message('with.arguments', :params => ['First', 'Two'], :default => 'Not found')

Of course the Rails framework provides other formatting methods like :

# localize dates or datetimes
l(date_or_time)

Java API

The component org.sonar.api.i18n.I18n is available for server extensions. Batch extensions are not supported yet and can not load bundles.

How to handle a Language Pack

A Language Pack defines bundles for the Sonar Platform and for Sonar Community Plugins.

Creating a new Language Pack

The easiest way to create a new pack is to copy the French Pack and to adapt it to your language.

Maintaining a Language Pack

Set the versions of the plugins that you want to translate in the pom file:

<properties>
    ...
    <!-- Versions of the plugins translated by this language pack -->
    <bundle.abacus>0.1</bundle.abacus>
    <bundle.branding>0.3</bundle.branding>
    <bundle.core>3.4-RC3</bundle.core>
    <bundle.javasquid>1.1</bundle.javasquid>
    <bundle.jira>1.0</bundle.jira>
    <bundle.motionchart>1.4</bundle.motionchart>
    <bundle.squidjava>1.0</bundle.squidjava>
    <bundle.violationdensity>1.2</bundle.violationdensity>
    ...
</properties>

 

To check the missing key, run:

mvn test

If the build fails, it means that some keys are missing. Go to target/l10n to check the reports for each bundle.

Missing keys are listed under 'Missing translations are:'

Missing translations are:
code_viewer.no_info_displayed_due_to_security=Due to security settings, no information can be displayed.
comparison.version.latest=LATEST
...

Each time you add a new bundle or you update an existing one, please create a JIRA ticket on the corresponding L10n component in order to track changes.

How to localize an independant plugin

This part applies if you are developing a commercial / closed-source plugin, or an open-source plugin that is not part of the Sonar Community Plugins.

Such plugins must embed their own bundles. Bundles must be added to src/main/resources with the following convention names :

The default bundle is mandatory, and must be the English translation. For example the plugin with key "mysonarplugin" must define the following files in order to enable the French translation: