Internationalization

The most evident requirement for internationalization support is the ability to display messages in several languages. This is built into Oxygen and it is one of the core services.

In every given moment an Oxygen application has a current language. This is the language of the interface, and all messages are automatically translated to this language. This is defined with the function Oxygen::SetLang(), or, if Oxygen is used as a controller, by the lang query string parameter. See the chapter on Setup for more info on setting up the languages.

All messages are served by the Lemma class, which can retrieve the translation from the linked dictionaries (again, this is described in Setup).

The constructor of the Lemma is overloaded:

$lemma1 = new Lemma(); // anonynmous empty lemma $lemma2 = new Lemma('Title'); // named empty lemma $lemma3 = new Lemma('en','Title','fr','Titre'); // anonymous lemma $lemma4 = new Lemma('Title','en','Title','fr','Titre'); // named lemma

However, in the majority of the cases, the lemma is retrieved by the Lemma::Pick() function:

$lemma = Lemma::Pick('Title'); // retrieves a lemma from the dictionaries

The __toString() method is overridden, and so each lemma can be directly reduced to a string which will be the translation to the current language. This is why the following code works:

echo Lemma::Pick('Title'); // Lemma will be converted to a string first. The conversion depends on the current language.

In most of the cases a Lemma can be used instead of a string. As a rule of thumb, there should be no hard codes string messages anywhere in the code. Instead, all messages should be stored in a dictionary and should be retrieved from there. This holds true even for single-language applications, because the dictionary serves as a centralised repository of all messages and makes review and editing easier.

The dictionary

The dictionary is built from a series of XML files (see the chapter on Setup). Each dictionary contains a number of lemmas. This is a simple example:

Title Titre Author Auteur Are you sure you want to delete this book? Voulez-vous vraiment supprimer ce livre ? ]]>

As a conversion, all messages begin with a capital letter. In addition, all Msg* lemmas should contain the punctuation, such as the question mark in the above example.

Placeholders

Sometimes, it is necessary to use placeholders inside the translation of a message, because the value varies. This can be done with the use of sprintf's format specifiers.

The author %s has written %d book(s). L'auteur %s a écrit %d livre(s). ]]>

The translation of these lemmas should be done with the use of the Sprintf method:

echo Lemma::Pick( 'MsgNumberOfBooksByAuthor' )->Sprintf( $author , $number_of_books );