Skip to end of metadata
Go to start of metadata

Purpose: help developers who would like to create new translations for the mapbuilder library, e.g. add a new supported language or add new messages to the existing languages.

MapBuilder I18N support

MapBuilder has I18N (Internationalization) support for texts. MapBuilder does not use hard-coded texts or messages; all language-specific strings reside in a file called the widgetText. There's also a possibility for a user to override or add just a few messages by means of the userWidgetText.

The widgetText file

The standard widgetText files in MapBuilder reside under the lib/text/ directory.
The actual path depends on the chosen language, e.g. if the current language is "en", the path to the widgetText would be:

/mapbuilder/lib/text/en/widgetText.xml

The structure of the widgetText file

The basic structure of the widgetText file is:

<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<WidgetText xmlns="http://mapbuilder.sourceforge.net/mapbuilder"
    version="0.2.1" id="mbDefaultText" xml:lang="en">
  <!-- Widget (XSL) messages -->
  <widgets>
    <AoiForm>
      <east>East:</east>
      <north>North:</north>
      <south>South:</south>
      <title>Area of interest coordinates</title>
      <west>West:</west>
    </AoiForm>
    [...]
  </widgets>

  <!-- JavaScript messages -->
  <messages>
    <aoiFormNotFound>Could not find aoiForm for geoSearch</aoiFormNotFound>
    <atLeastOneValue>Please enter at least one value, before proceeding</atLeastOneValue>
    <buttonBarRequired>buttonBar property required for object: {0}</buttonBarRequired>
    <cantCalculateDistance>Measurement does not know how to calculate the distanc</cantCalculateDistance>
    <cantGoBack>You can't go further back</cantGoBack>
    [...]
  </messages>
</WidgetText>

There are two main areas: <widgets/> and <messages/>. Both serve different purposes. The XML elements under <widgets/> are added as parameters to the stylesheet (XSL) for the named widget. The XML elements under <messages/> can be looked up from the JavaScript objects using the utility function mbGetMessage().

Widget messages

Widget messages are added as parameters before processing the stylesheet (XSL) for the named widget. From the example widgetText above, the widget named AoiForm in the MapBuilder configuration (the XML element name, not the id attribute) has five parameters added: east, north, south, title and west. From within the stylesheet, these can be declared as <xsl:param name="paramName"/>:

<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  [...]
  <!-- Text params for this widget -->
  <xsl:param name="title"/>
  <xsl:param name="north"/>
  <xsl:param name="south"/>
  <xsl:param name="east"/>
  <xsl:param name="west"/>
  [...]

Using e.g. the title parameter further down in the stylesheet is as simple as:

          <th align="left" colspan="3">
            <xsl:value-of select="$title"/>
          </th>

The title that's shown in the header of the AoiForm widget is in the correct language.

JavaScript messages

From within the JavaScript objects, messages can be retrieved using the mbGetMessage() function. From the example widgetText above:

would set the JavaScript variable message to "Could not find aoiForm for geoSearch" (if the language was "en"). For simple messages, that's all there is to it. Furthermore, mbGetMessage() also supports parameterized messages! You may have noticed the <buttonBarRequired/> element in the example widgetText:

    <buttonBarRequired>buttonBar property required for object: {0}</buttonBarRequired>

Patterns of the format {0} (and {1}, {2} etc.) are replaced with optional positional parameters to the mbGetMessage() call:

This would set the JavaScript variable message to "buttonBar property required for object: Back". For formatting, mbGetMessage() uses the mbFormatMessage() function; see the JSDoc descriptions for mbFormatMessage() and mbGetMessage() for more information.

Language selection

Selecting the language MapBuilder uses can be as simple as adding a parameter "language=en" to the MapBuilder URL. Currently, MapBuilder has support for:

  • en - English
  • fr - Français (French)
  • it - Italiano (Italian)
  • nl - Nederlands (Dutch)

If an unsupported language is selected, MapBuilder falls back on the default language, "en". See the I18N example for a demonstration of this.

Adding a new language

If you want to extend the list of supported languages, start by creating a new sub-directory for the new language under the lib/text/ directory; use the official abbreviation from the IANA Language Subtag Registry.

Note: Although MapBuilder currently does not use additional subtags like "en-GB" and has currently no support for falling back on a more general language tag if an unsupported regional subtag is specified, you could still add a sub-directory "en-GB" to support British English. See this W3C article for background information on language tags.

Copy the widgetText.xml from lib/text/en/widgetText.xml to your new sub-directory. Then translate all messages; please keep the widgets and widget texts, and the message keys, in alphabetical order and keep the capitalisation and punctuation consistent! Commit your new language to the repository. It would be nice if you could volunteer to translate additional messages that may appear in future versions of MapBuilder to your new language.

Adding new text

If you add a new widget, or just add new text to an existing widget, or add new messages to a JavaScript object, start by adding the text in the approriate place in the English widgetText under the lib/text/ directory, lib/text/en/widgetText.xml. Please keep the widgets and widget texts, and the message keys, in alphabetical order and keep the capitalisation and punctuation consistent! Choose a meaningful message key; e.g. a tooltip for a new button should be called <tooltip/> (then it will automatically be used as a tooltip for the button by lib/widget/Button.xsl). Look at the other message keys for guidance.

When you've added them to the English widgetText, copy the newly added elements to all the other languages under the lib/text/ directory and add an XML comment indicating that these messages need to be translated like so:

  <messages>
    [...]
    <myNewMessageKey>This is my new message key!</myNewMessageKey>  <!-- TODO: translate -->
    [...]
  </messages>

Then either translate the new messages yourself if you can, or ask the other MapBuilder developers to help you on the mapbuilder-devel mailing list.

The user widgetText file

The location of the user widgetText files is specified in the MapBuilder configuration:

<userWidgetTextDir>myText</userWidgetTextDir>

MapBuilder looks for the user widgetText files under the speficied userWidgetTextDir directory. The actual path also depends on the chosen language, e.g. if the current language is "en", the path to the user widgetText would be:

myText/en/widgetText.xml

The structure of the user widgetText file

The structure of the (completely optional) user widgetText file is exactly identical to the widgetText file.
If the user widgetText contains e.g.:

<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<WidgetText xmlns="http://mapbuilder.sourceforge.net/mapbuilder"
    version="0.2.1" id="mbDefaultText" xml:lang="en">
  <!-- User JavaScript messages -->
  <messages>
    <cantGoBack>There's no turning back, I'm afraid...</cantGoBack>
  </messages>
</WidgetText>

then the message shown for cantGoBack would be "There's no turning back, I'm afraid..." instead of the usual "You can't go further back".

Adding user text

If you add a custom widget to your application, or want to override some of the default messages or texts, the user widgetText is just the place for you. Create a userWidgetTextDir, create subdirectories for the languages you want to support, and create a widgetText.xml containing your messages.

If you select a language in your application for which there is no user widgetText, it will fall back on the default language "en" for these messages.

  • No labels