Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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:

  • Translations for the Sonar SonarQube Platform: making the Sonar SonarQube Platform available in a new language requires you to develop and publish a new Language Pack plugin.
    • By default Sonar default SonarQube embeds the English Pack.
    • All other Language Pack plugins (like the French Pack plugin) are hosted in the Plugins Forge, are maintained by the community, and are available through Update Center (category "Localization").
  • Translations for the Sonar the SonarQube Community Plugins: open-source plugins of the Sonar from the SonarQube Community (hosted in the Plugins Forge) must embed only the bundles for the default locale (en). Translations will be done in the Language Pack plugins.

  • Translations for other Plugins: closed-source/commercial/independant independent plugins must embed the bundles for the default locale and the translations for every language they want to support.
Tip
titleTo sum up
  • Sonar SonarQube Platform and Sonar and SonarQube Community Plugins rely on Language Pack plugins to get for translations
  • Other independant Sonar independent SonarQube plugins must themselves embed by themselves all the translations they need

Translation

...

Bundles

There are two types of files for localized messages:

Properties files

Localized messages are stored in properties files:

  • These are regular properties files with key/value pairs where you will put most translations
  • These files must be stored in the package "org.sonar.l10n" package (usually in the directory src/main/resources/org/sonar/l10n directory)
  • The name names of these files must respect follow the convention "<key of the plugin to translate>_<language>.properties", for example "technicaldebt_fr.properties" or "core_fr.properties". See sonar-packaging-maven-plugin for details on plugin key derivation.
  • Messages can accept arguments. Such entries would look like:

    No Format
    myplugin.foo=This is a message with 2 params: the first "{0}" and the second "{1}".
    

HTML files

  • They are used for rule descriptions, which might be long and need HTML tags
  • These files must be stored in the package "org.sonar.l10n.<plugin key>_<language>"
    • Starting with Sonar 3.0, the files should be stored in the package "org.sonar.l10n.<key of the plugin to translate>_<language>.rules.<repository key>" (backward compatibility is ensured for l10n plugins which use the former location)
  • The name of these files must be the key of the rule they translate
  • Example: the French description of the Squid Architectural Constraint rule is "src/main/resources/org/sonar/l10n/squidjava_fr/ArchitecturalConstraint.html"
    • Or, starting with Sonar 3.0: "src/main/resources/org/sonar/l10n/squidjava_fr/rules/squid/ArchitecturalConstraint.html" (as "squidjava" is the plugin key and "squid" the repository key)
Warning
titleUTF-8 encoding

In the Java API, properties files are supposed to be encoded in ISO-8859 charset. Without good tooling, this it can be quite annoying to write translation translations for languages that do not fit in this charset.
This is why we deciced decided 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 is what you need to know about conventions for keys:

paramalerts.param.threshold=Thresholdwidget.<key>.

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>.
property.<property key>.name
Name of widget property
widget.hotspot_most_violated_rules.property.defaultSeverity.name=Default severity
widget.<key>.property.<property key>.desc
Description of widget property
widget.
hotspot_most_violated_rules.property.defaultSeverity.desc=If selected, 
severity used to initialize the dropdown list of widget
widget.<key>.property.<property>.option.<option>.name
Name of item of dropdown list 

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 key>

Category name of properties, since 2.11

property.category.General=Général

property.category.<category key>.description
Short description of category of properties, since 3.6property.category.General.description=General properties of SonarQube
property.category.<category key>.<subcategory key>
Subcategory name of properties, since 3.6property.category.exclusions.global=Global exclusions
property.category.<category key>.<subcategory key>.descriptionShort description of subcategory of properties, since 3.6property.category.exclusions.global.description=Configuration of global exclusions

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

 

Deprecated - HTML Files for Rule Descriptions

Rule descriptions could be translated through HTML files in versions prior to 4.1.

  • They are used for rule descriptions, which might be long and need HTML tags
  • The files should be stored in the org.sonar.l10n.<key of the plugin to translate>_<language>.rules.<repository key> package.
    • Before SonarQube 3.0, the location is org.sonar.l10n.<plugin key>_<language> package. Backward compatibility is ensured for l10n plugins which use this old location.
  • The names of these files should correspond to the keys of the rules they translate
  • Example: the French description of the Squid Architectural Constraint rule is: src/main/resources/org/sonar/l10n/squidjava_fr/rules/squid/ArchitecturalConstraint.html (since squidjava is the plugin key, and squid is the repository key)
    • Prior to SonarQube 3.0: src/main/resources/org/sonar/l10n/squidjava_fr/ArchitecturalConstraint.html
  • Supported tags are:
    • <p> for paragraphs. Must be used for each paragraph.
    • <ul> and <ul> for lists
    • <h2> and <h3> for titles and subtitles (since version 3.7.1)
    • <blockquote> for quotations (since version 3.7.1)
    • <code> for short code in paragraph
    • <pre> for block of code
    • <table class="rule-table">, with <thead><tr><th> and <tbody><tr><td> cells (since version 3.7.1)

How to use localized messages?

...

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

Code Block
message(property_key, options={})

...

Code Block
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 :

...

A Language Pack defines bundles for the Sonar Platform SonarQube platform and for Sonar Community Pluginsthe SonarQube 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 In the pom file, set the versions of the plugins that you want to translate in the pom file:

Code Block
titlepom.xml
languagehtml/xml
<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, When it's time to update your language pack for a new version of SonarQube or a plugin, the easiest way to see what keys are missing is to run:

Code Block
languagenone
mvn test

...

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

...

independent plugin

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

Such plugins If your plugin falls in this category, it must embed their its own bundles. Bundles must be added to src/main/resources with the following naming convention names :

  • Standard messages : org/sonar/l10n/<plugin key>_<language>.properties
  • Rule descriptions :
    Up to Sonar 3.0: (prior to version 4.2) :
    • org/sonar/l10n/<plugin key>_<language>/rules/<repository key>/*.html
        Since Sonar
        • Prior to version 3.0 : org/sonar/l10n/<plugin key>_<language>/
        rules/<repository key>/
        • *.html

    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:

    • org/sonar/l10n/mysonarplugin.properties
    • org/sonar/l10n/mysonarplugin_fr.properties