Translation Entity

When you are designing a UI file in an XML format -- such as SVG -- you can localize your elements using XML entities.

Say we are writing an SVG UI, and we want to display the score. So we create some SVG boxes, and label them with:

  <text x="0" y="0" id="score">0</text>
  <text x="0" y="10">Victory Points</text>

The first of these is fine; digits are readable by everybody. (We give the element an id so that your UI script code can change the text as the score changes.)

The second is not so great -- it's hardwired to English. We would like to set up the UI so that it can easily be extended for other languages.

Defining Translation Entities

To do this, make sure you have a locale directory in your UI package. This directory should have a subdirectory for each language you want to support: locale/en for English, locale/de for German, and so on. You can add these one at a time. For now, we'll start with English.

Create a file locale/en/message.def.

(In fact, this can have any name, as long as it's inside the locale/en directory. We will use message.def throughout this example.)

This file can contain any number of XML entity definitions. A definition would look like this:

  <!ENTITY vpoints "Victory Points">

You should create one message.def file for each language you want to support. They must all define the same entities. The German one, then, would look like:

  <!ENTITY vpoints "Siegpunkt">

The Magic Vollocp Header

In order to use these entities, your SVG file must undertake the proper ritual. That is to say, it must have define and invoke a magic URL in its DOCTYPE header.

We shall not go into the arcanities of how the ritual works. Just copy this:

  <?xml version="1.0"?>
  <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
    "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
  <!ENTITY % localedef SYSTEM "vollocp://locale/message.def?en,de#lang">
  %localedef; %lang;
  ]>

The two magical lines go inside square brackets at the end of the <!DOCTYPE> tag.

Ok, we'll go into some arcanities. You shall recognize the message.def part of the header; this is the name shared by the files you created in each locale subdirectory.

The ?en,de part is the list of languages you support. This list must match the list of locale subdirectories which contain message.def files. In this case, we're declaring that locale/en/message.def and locale/de/message.def exist.

(By the way, the order of languages in your list is significant. If a player's client is set to some language you have not defined, it will default to the first language on your list.)

Using Translation Entities

Now that your files are in place and your header is set up, you can use the entities you've defined.

  <text x="0" y="0" id="score">0</text>
  <text x="0" y="10">&vpoints;</text>

The &vpoints; entity works just like the HTML entities you're familiar with -- &amp; and so on. When it appears in the SVG file, its equivalent text is substituted automatically. But because of the magic header, the client substitutes the text according to the player's language preference. If the player has set his Volity client to English, he'll see "Victory Points". If he's chosen German, he'll see "Siegpunkt" instead.

(If he's chosen any other language, he'll get "Victory Points". You've only defined two languages, and any other preference defaults to the first language on your list: English.)

Adding New Languages

Create a new message.def file -- say, locale/fr/message.def.

Add the language code to the header line:

  <!ENTITY % localedef SYSTEM "vollocp://locale/message.def?en,de,fr#lang">

Presto, you have added support for a new language.

Loading Language-Specific SVG Files

Instead of defining XML entities, you can translate an entire SVG file, and then use this system to load SVG elements from it.

You do not translate the main.svg file. Instead, create a secondary file in locale/en -- say, locale/en/objects.svg.

Define appropriate elements in this file:

  <text x="0" y="10" id="scorelabel">Victory Points</text>

Then, for each other language you wish to support, create an appropriate translation. In locale/de/objects.svg, you would have:

  <text x="0" y="10" id="scorelabel">Siegpunkt</text>

...and so on. Again, each of these files must contain the same elements.

Once again, your main.svg UI file must contain the magic header. However, the various objects.svg files must not contain the magic header lines. Trust me on this.

Your main.svg can then import elements from the appropriate objects.svg, by doing this:

  <use xlink:href="locale/&lang;/objects.svg#scorelabel" />

This works because the &lang; entity is defined to be the appropriate string -- en, de, etc -- according to the player's language preference.

(Again, if he has chosen a language you do not support, he'll get the first language on your list. This is why it's critical that the ?en,de part of the header list the languages that you actually support. If you leave one out, the player won't be able to see it, even if you have a locale subdirectory set up.)