Quick Search
Browse
Pages
Blog
Labels
Attachments
Mail
Advanced
What’s New
Space Directory
Feed Builder
Keyboard Shortcuts
Confluence Gadgets
Log In
Sign Up
Dashboard
Sonar
Copy Page
You are not logged in. Any changes you make will be marked as
anonymous
. You may want to
Log In
if you already have an account. You can also
Sign Up
for a new account.
This page is being edited by
.
Paragraph
Paragraph
Heading 1
Heading 2
Heading 3
Heading 4
Heading 5
Heading 6
Preformatted
Quote
Bold
Italic
Underline
More colours
Strikethrough
Subscript
Superscript
Monospace
Clear Formatting
Bullet list
Numbered list
Outdent
Indent
Align left
Align center
Align right
Link
Table
Insert
Insert Content
Image
Link
Attachment
Symbol
Emoticon
Wiki Markup
Horizontal rule
tinymce.confluence.insert_menu.macro_desc
Info
JIRA Issue
Status
Gallery
Tasklist
Table of Contents
Other Macros
Page Layout
No Layout
Two column (simple)
Two column (simple, left sidebar)
Two column (simple, right sidebar)
Three column (simple)
Two column
Two column (left sidebar)
Two column (right sidebar)
Three column
Three column (left and right sidebars)
Undo
Redo
Find/Replace
Keyboard Shortcuts Help
<table class="wysiwyg-macro" data-macro-name="info" data-macro-parameters="icon=false|title=Table of Contents" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2luZm86aWNvbj1mYWxzZXx0aXRsZT1UYWJsZSBvZiBDb250ZW50c30&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"><p><img class="editor-inline-macro" src="/plugins/servlet/confluence/placeholder/macro?definition=e3RvY30&locale=en_GB&version=2" data-macro-name="toc"></p></td></tr></table><p> </p><p>This page gives guidelines to I18n for:</p><ul><li>Plugin developers who would like to apply the i18n mechanism in their own plugin, so that this plugin can be available in several languages</li><li>People who would like to help the community by making the platform available in a new language</li></ul><h1>Principles</h1><p>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:</p><ul><li><strong>Translations for the Sonar Platform</strong>: making the Sonar Platform available in a new language requires to develop and publish a new Language Pack plugin. <br /><ul><li>By default Sonar embeds the English Pack.</li><li>All other Language Pack plugins (like the French Pack plugin) are hosted in the <a href="https://github.com/SonarCommunity">Plugins Forge</a>, are maintained by the community and are available through Update Center (category "Localization").</li></ul></li></ul><ul><li><strong>Translations for the Sonar Community Plugins</strong>: open-source plugins of the Sonar Community (hosted in the Plugins Forge) must embed <u>only the bundles for the default locale</u>. Translations will be done in the Language Pack plugins.<br /><br /></li><li><strong>Translations for other Plugins</strong>: closed-source/commercial/independant plugins must embed the bundles for the default locale <strong>and</strong> the translations for every language they want to support.</li></ul><table class="wysiwyg-macro" data-macro-name="tip" data-macro-parameters="title=To sum up" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e3RpcDp0aXRsZT1UbyBzdW0gdXB9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"><ul><li><strong>Sonar Platform and Sonar Community Plugins rely on Language Pack plugins to get translations</strong></li><li><strong>Other independant Sonar plugins embed by themselves all the translations they need</strong></li></ul></td></tr></table><h1>Translation Bundles</h1><p>There are two types of files for localized messages:</p><h4>Properties files</h4><ul><li>These are regular properties files with key/value pairs where you will put most translations</li><li>These files must be stored in the package "org.sonar.l10n" (usually in the directory src/main/resources/org/sonar/l10n)</li><li>The name of these files must respect the convention "<key of the plugin to translate>_<language>.properties", for example "technicaldebt_fr.properties" or "core_fr.properties". See <a class="confluence-link" href="/display/SONAR/sonar-packaging-maven-plugin" data-linked-resource-id="186187965" data-linked-resource-type="page" data-linked-resource-default-alias="sonar-packaging-maven-plugin" data-base-url="http://docs.codehaus.org">sonar-packaging-maven-plugin</a> for details on plugin key derivation.</li><li><p>Messages accept arguments. Such entries would look like:</p><table class="wysiwyg-macro" data-macro-name="noformat" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e25vZm9ybWF0fQ&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>myplugin.foo=This is a message with 2 params: the first "{0}" and the second "{1}". </pre></td></tr></table></li></ul><h4>HTML files</h4><ul><li>They are used for rule descriptions, which might be long and need HTML tags</li><li>These files must be stored in the package "org.sonar.l10n.<plugin key>_<language>"<br /><ul><li>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)</li></ul></li><li>The name of these files must be the key of the rule they translate</li><li><u><strong>Example</strong></u>: the French description of the Squid Architectural Constraint rule is "src/main/resources/org/sonar/l10n/squidjava_fr/ArchitecturalConstraint.html"<br /><ul><li>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)</li></ul></li></ul><table class="wysiwyg-macro" data-macro-name="warning" data-macro-parameters="title=UTF-8 encoding" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e3dhcm5pbmc6dGl0bGU9VVRGLTggZW5jb2Rpbmd9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="RICH_TEXT"><tr><td class="wysiwyg-macro-body"><p>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.<br /> <strong>This is why we decided to encode the properties files in UTF-8</strong>, 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.<br /> <strong>HTML files must also be encoded in UTF-8.</strong></p></td></tr></table><h4>Naming conventions for keys</h4><p>Here are the conventions you have to know about keys:</p><table class="confluenceTable"><tbody><tr><th class="confluenceTh"><p>Key</p></th><th class="confluenceTh"><p>Description</p></th><th class="confluenceTh"><p>Example</p></th></tr><tr><td class="confluenceTd"><p><code>metric.<key>.name</code></p></td><td class="confluenceTd"><p>Metric name</p></td><td class="confluenceTd"><p><code>metric.ncloc.name=Lines of code</code></p></td></tr><tr><td class="confluenceTd"><p><code>metric.<key>.description</code></p></td><td class="confluenceTd"><p>Metric description</p></td><td class="confluenceTd"><p><code>metric.ncloc.description=Non Commenting Lines of Code</code></p></td></tr><tr><td class="confluenceTd"><p><code>notification.channel.<channel key></code></p></td><td class="confluenceTd"><p>Name of notification channel</p></td><td class="confluenceTd"><p><code>notification.channel.EmailNotificationChannel=Email</code></p></td></tr><tr><td class="confluenceTd"><p><code>notification.dispatcher.<dispatcher key></code></p></td><td class="confluenceTd"><p>Subscription to notification channel</p></td><td class="confluenceTd"><p><code>notification.dispatcher.ChangesInReviewAssignedToMeOrCreatedByMe=Changes in review assigned to me or created by me</code></p></td></tr><tr><td class="confluenceTd"><p><code>rule.<repository>.<key>.name</code></p></td><td class="confluenceTd"><p>Rule name</p></td><td class="confluenceTd"><p><code>rule.pmd.StringInstantiation.name=String Instantiation</code></p></td></tr><tr><td class="confluenceTd"><p><code>rule.<repository>.<key>.param.<param key></code></p></td><td class="confluenceTd"><p>Description of rule parameter</p></td><td class="confluenceTd"><p><code>rule.pmd.VariableNamingConventions.param.memberSuffix=Suffix for member variables</code></p></td></tr><tr><td colspan="1" class="confluenceTd"><code>dashboard.<key>.name</code></td><td colspan="1" class="confluenceTd">Dashboard name, since 2.14.</td><td colspan="1" class="confluenceTd"><code>dashboard.Hotstpots.name=Point Chauds</code></td></tr><tr><td colspan="1" class="confluenceTd"><p><code>qualifier.<key></code></p><p><code>qualifiers.<key></code></p></td><td colspan="1" class="confluenceTd">Qualifier name, since 2.13.</td><td colspan="1" class="confluenceTd"><p><code>qualifier.TRK=Project</code></p><p><code>qualifiers.TRK=Projects</code></p></td></tr><tr><td class="confluenceTd"><p><code>widget.<key>.name</code></p></td><td class="confluenceTd"><p>Widget name</p></td><td class="confluenceTd"><p><code>widget.alerts.name=Alerts</code></p></td></tr><tr><td class="confluenceTd"><p><code>widget.<key>.description</code></p></td><td class="confluenceTd"><p>Widget description</p></td><td class="confluenceTd"><p><code>widget.alerts.description=Display project alerts</code></p></td></tr><tr><td colspan="1" class="confluenceTd"><pre>widget.<key>.property.<property key>.name</pre></td><td colspan="1" class="confluenceTd">Name of widget property</td><td colspan="1" class="confluenceTd"><pre>widget.hotspot_most_violated_rules.property.defaultSeverity.name=Default severity</pre></td></tr><tr><td colspan="1" class="confluenceTd"><pre>widget.<key>.property.<property key>.desc</pre></td><td colspan="1" class="confluenceTd">Description of widget property</td><td colspan="1" class="confluenceTd"><pre>widget.hotspot_most_violated_rules.property.defaultSeverity.desc=If selected, <br />severity used to initialize the dropdown list of widget</pre></td></tr><tr><td colspan="1" class="confluenceTd"><pre>widget.<key>.property.<property>.option.<option>.name</pre></td><td colspan="1" class="confluenceTd">Name of item of dropdown list</td><td colspan="1" class="confluenceTd"> </td></tr><tr><td class="confluenceTd"><p><code>widget.<key>.*</code></p></td><td class="confluenceTd"><p>Any other widget message</p></td><td class="confluenceTd"><p><code>widget.alerts.tooltip=Threshold is raised</code></p></td></tr><tr><td class="confluenceTd"><p><code><page key>.page</code></p></td><td class="confluenceTd"><p>Page names shown in the left sidebar</p></td><td class="confluenceTd"><p><code>cloud.page=Cloud</code></p></td></tr><tr><td class="confluenceTd"><p><code><page key>.*</code></p></td><td class="confluenceTd"><p>Any other keys used in a page</p></td><td class="confluenceTd"><p><code>cloud.size=Size</code></p></td></tr><tr><td class="confluenceTd"><p><code>property.category.<code><category key></code></code></p></td><td class="confluenceTd"><p>Category name of properties, since 2.11</p></td><td class="confluenceTd"><p><code>property.category.General=Général</code></p></td></tr><tr><td colspan="1" class="confluenceTd"><code>property.category.<category key>.description<br /></code></td><td colspan="1" class="confluenceTd">Short description of category of properties, since 3.6</td><td colspan="1" class="confluenceTd"><code>property.category.General.description=General properties of Sonar<br /></code></td></tr><tr><td colspan="1" class="confluenceTd"><code>property.category.<code><category key>.<subcategory key><br /></code></code></td><td colspan="1" class="confluenceTd">Subcategory name of properties, since 3.6</td><td colspan="1" class="confluenceTd"><code>property.category.exclusions.global=Global exclusions<br /></code></td></tr><tr><td colspan="1" class="confluenceTd"><code>property.category.<code><category key>.<subcategory key>.description</code></code></td><td colspan="1" class="confluenceTd">Short description of subcategory of properties, since 3.6</td><td colspan="1" class="confluenceTd"><code>property.category.exclusions.global.description=Configuration of global exclusions<br /></code></td></tr><tr><td class="confluenceTd"><p><code>property.<key>.name</code></p></td><td class="confluenceTd"><p>Property name, since 2.11</p></td><td class="confluenceTd"><p><code>property.sonar.sourceEncoding.name=Source encoding</code></p></td></tr><tr><td class="confluenceTd"><p><code>property.<key>.description</code></p></td><td class="confluenceTd"><p>Property description, since 2.11</p></td><td class="confluenceTd"><p><code>property.sonar.sourceEncoding.description=Source encoding</code></p></td></tr><tr><td class="confluenceTd"><p><code><plugin key>.*</code></p></td><td class="confluenceTd"><p>Any other keys used by plugin</p></td><td class="confluenceTd"><p> </p></td></tr></tbody></table><h1>How to use localized messages ?</h1><h3>Ruby on Rails API</h3><p>This API is used when implementing Ruby widgets or pages. It's really simple, a single method must be used :</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>message(property_key, options={}) </pre></td></tr></table><p>Options are :</p><ul><li><code>:default</code> is the default value when the property key does not exist in bundles. If it's not set, then the key itself is returned.</li><li><code>:params</code> is an array of string message arguments.</li></ul><p>Examples :</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>message('cloud.size') message('cloud.size', :default => 'Cloud') message('with.arguments', :params => ['First', 'Two']) message('with.arguments', :params => ['First', 'Two'], :default => 'Not found') </pre></td></tr></table><p>Of course the Rails framework provides other formatting methods like :</p><table class="wysiwyg-macro" data-macro-name="code" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre># localize dates or datetimes l(date_or_time) </pre></td></tr></table><h3>Java API</h3><p>The component <code>org.sonar.api.i18n.I18n</code> is available for <strong>server extensions</strong>. Batch extensions are not supported yet and can not load bundles.</p><h1>How to handle a Language Pack</h1><p>A Language Pack defines bundles for the Sonar Platform <u>and</u> for the Sonar Community plugins.</p><h3>Creating a new Language Pack</h3><p>The easiest way to create a new pack is to copy the <a href="https://github.com/SonarCommunity/sonar-l10n-fr">French Pack</a> and to adapt it to your language.</p><h3>Maintaining a Language Pack</h3><p>Set the versions of the plugins that you want to translate in the pom file:</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-parameters="language=html/xml|title=pom.xml" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6dGl0bGU9cG9tLnhtbHxsYW5ndWFnZT1odG1sL3htbH0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre><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> </pre></td></tr></table><p> </p><p>To check the missing key, run:</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-parameters="language=none" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6bGFuZ3VhZ2U9bm9uZX0&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>mvn test</pre></td></tr></table><p><span style="font-size: 10.0pt;line-height: 13.0pt;">If the build fails, it means that some keys are missing. Go to target/l10n to check the reports for each bundle.</span></p><p>Missing keys are listed under 'Missing translations are:'</p><table class="wysiwyg-macro" data-macro-name="code" data-macro-parameters="language=none|title=Report" style="background-image: url(/plugins/servlet/confluence/placeholder/macro-heading?definition=e2NvZGU6dGl0bGU9UmVwb3J0fGxhbmd1YWdlPW5vbmV9&locale=en_GB&version=2); background-repeat: no-repeat;" data-macro-body-type="PLAIN_TEXT"><tr><td class="wysiwyg-macro-body"><pre>Missing translations are: code_viewer.no_info_displayed_due_to_security=Due to security settings, no information can be displayed. comparison.version.latest=LATEST ...</pre></td></tr></table><p><span style="font-size: 10.0pt;line-height: 13.0pt;">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.</span></p><h1>How to localize an independant plugin</h1><p><em>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.</em></p><p>Such plugins must embed their own bundles. Bundles must be added to src/main/resources with the following convention names :</p><ul><li><strong>Standard messages : org/sonar/l10n/<plugin key>_<language>.properties</strong></li><li>Rule descriptions : <br /><ul><li>Up to Sonar 3.0: org/sonar/l10n/<plugin key>_<language>/*.html</li><li><strong>Since Sonar 3.0: org/sonar/l10n/<plugin key>_<language>/rules/<repository key>/*.html</strong></li></ul></li></ul><p>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:</p><ul><li>org/sonar/l10n/mysonarplugin.properties</li><li>org/sonar/l10n/mysonarplugin_fr.properties</li></ul><p> </p>
Please type the word appearing in the picture.
Attachments
Labels
Location
Watch this page
< Edit
Preview >
Loading…
Save
Cancel
Next hint
search
attachments
weblink
advanced