Internationalization & localization
Internationalization of an application requires to identify all language dependent resources and make them exchangeable for the actual localization into a specific language. This includes static and dynamic texts as well as images. Since images are referenced by their filename or represented as text (e.g. base64 encoded), it is sufficient to focus on text.
Static text
Static text refers to text used in application templates or messages generated while the application is executed. To keep the application code language agnostic only so called text identifiers are used in these places and the actual translation is retrieved by calling the Message::getText
method:
- Note
- Implementations of
Message
must return the text identifier, if no translation is found or the translation is empty. This helps to simplify the translation process, if the default language is used in text identifiers. In this case, no translation is required for the default language.
If no language parameter is passed to the Message::getText
method, the returned translation will be in the application's default user interface language. This language is determined in the following way:
- Use the value of the
language
parameter of theMessage
configuration section - If not defined use the value of the global variable
$_SERVER['HTTP_ACCEPT_LANGUAGE']
If parts of the text vary depending on the application state, it is necessary to put variables into the text identifier. Variable names are %0%
, %1%
, ... and they are replaced in the order of the values passed into the Message::getText
method:
Template text
wCMF provides the translate
plugin for embedding language dependent text into Smarty templates. The plugin is automatically included and used in the following way:
Localization
Since Message
defines the interface, it needs concrete implementations to actually get the translations. The FileMessage
class retrieves translations from the file system. It expects one file per language defining a language dependent array that maps text identifiers to translations. The language code (e.g. en) is used to identify the language of the translation. The file must be named like messages_code.php, the variable like $messages_code.
The following examples show definitions for English (en) and German (de) texts, where the array keys are the text identifiers used in the application and the values are the translations in the appropriate language.
messages_en.php
messages_de.php
- Note
- Note that the text identifiers are in the application's default language (en) and therefor no translations need to be provided.
The default configuration of Message
is as follows:
The parameter localeDir
defines the directory where FileMessage
searchs for translation files and the language
parameter defines the application's default language.
Tools
The default application ships with a tool for finding translatable text and generating localization files from it. After installing the application it is available under http://localhost/wcmf-default-app/tools/locale/
.
The tool uses I18nUtil
internally to search for occurrences of
->getText('Text to translate', ...)
as used in$message->getText('Text to translate', ...)
in PHP code{translate:"Text to translate" ...}
as used in Smarty templatesDict.translate("Text to translate", ...)
as used in the Javascript code of the default application
Text to translate is supposed to be the message to be localized. The tool generates one localization file for each language puts it into the appropriate directory. It's capable of merging already existing translations into the newly generated files.
The tool's configuration is defined in the file config.ini in the tool's directory and defaults to:
Model content
Model content is initially created in the application's default model language, which might differ from the default user interface language (see Static text). Localization of the model content is done by using implementations of Localization
. The interface defines methods for loading and saving localized model content. The following code demonstrates how to use it to get translated content:
Localization
There are several strategies for storing localized versions of the content, all having advantages and disadvantages regarding extensibility and performance. The idea behind the DefaultLocalization
implementation is to keep the domain model clear of localization related attributes by storing translations in a separate entity type. Using one entity type for all content leads to more flexibility when extending the domain model.
The translation entity type must have the following attributes:
objectid
object id of the translated entity (e.g. Book:1)attribute
translated attribute (e.g. title)language
the language code of the translation (e.g. en)translation
the actual translation
The supported content languages are either defined in the Languages
configuration section (see below) or in the language entity type that is used by DefaultLocalization
, if the configuration section does not exist.
The language entity type must have the following attributes:
code
language code (e.g. en)name
language name (e.g. English)
The following example demonstrates the creation of localized content using the Localization
interface:
The localization configuration of the default application is the following:
In this example the default model language is set to English and the language entity type is ignored, because the available languages are defined in the configuration.