What developers need to know/do

Hudson's i18n support has two aspects that developers need to be aware of.

  1. Generation of type-safe Messages classes from Messages.properties
  2. Marking messages in jelly files

Generation of Messages classes

Hudson uses localizer to generate classes for accessing message resources in a type-safe way. For each src/main/resources/**/Messages.properties, a Messages class is generated. See the referenced page for how this class looks like. If your IDE fails to find these classes, manually add "target/generated-sources/localizer" directory to your source root.

Wherever the code returns a String for display purpose (such as Descriptor.getDisplayName()), use the Messages class to obtain a localized message. At the runtime, a proper locale is selected automatically. A typical workflow for this is as follows:

  1. You identify messages that need be localized
  2. You place that in Messages.properties. One can choose to have this file for each package, or you could just have one such file for the whole module/plugin.
  3. You run mvn compile once to re-generate Messages.java
  4. Update your code to use the newly generated message formatting method

As usual, looking at how the core code does this might help you get the idea of how to do this.

Marking messages in jelly files

Your jelly files in src/main/resources often contain messages that need to be localized, and those need to be marked as well.

In the simplest case, suppose you have a part of a Jelly file that looks like the following:

<h1>Output</h1>
<p>...</p>

Then all you need to do is to change this to the following:

<h1>${%Output}</h1>
<p>...</p>

The ${%...} marker indicates stapler to look for localized resources, and when none is found it'll just print "Output" for this, which is what you want.

Let's consider the case where the localization requires parameters. Suppose you have a Jelly file foo.jelly like this:

<p>Click <a href="${obj.someMethod(a,b,c)}">here</a></p>

In this case, first you have to write foo.properties for the default locale:

click.here.link=Click <a href="{0}">here</a>

Then update foo.jelly to refer to this like this:

<p>${%click.here.link(obj.someMethod(a,b,c))}</p>

If you have multiple parameters you can pass them by separating ',' (just like a function call), and from property files you can reference them as {0}, {1}, etc., by following the MessageFormat class convention.