Localization

Contents...

Webasyst framework has built-in support for multi-lingual applications. The localization mechanism utilizes the functions provided by PHP extension gettext or, if it is not installed on the server, similar functions written in PHP are used.

Localization of apps

To display string word translated to the current user language, you can use the following syntax:

If no translation for string word is found, the string is displayed without translation: word.

gettext localization files containing translations of interface strings to other languages must be placed inside the application file system according to following rule: wa-apps/[APP_ID]/locale/[LOCALE]/LC_MESSAGES/[APP_ID].po. For example, a localization file containing translation of text strings used in an application with the blog identifier into the Russian language must be located at wa-apps/[APP_ID]/locale/ru_RU/LC_MESSAGES/blog.po.

A file with the .po extension is a text file of in a special format, which contains translations of text strings for a specific language locale. In order to allow the application to use translations from a .po file, the file must be compiled to a file with the .mo extension; e.g., using the popular poEdit program.

Below is shown an example of a .po file containing translations into Russian:

msgid ""
msgstr ""
"Project-Id-Version: Guestbook\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2011-04-27 10:30+0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=((((n%10)==1)&&((n%100)!=11))?(0):(((((n%10)>=2)&&
((n%10)<=4))&&(((n%100)<10)||((n%100)>=20)))?(1):2));\n"
"X-Poedit-Language: Russian\n"
"X-Poedit-Country: Russian Federation\n"
"X-Poedit-SourceCharset: utf-8\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-SearchPath-0: .\n"
"X-Poedit-SearchPath-1: .\n"

msgid "Name"
msgstr "Имя"

msgid "Message"
msgstr "Сообщение"

msgid "post"
msgid_plural "posts"
msgstr[0] "запись"
msgstr[1] "записи"
msgstr[2] "записей"

"Key–translation" pairs

A localization key and its translation are represented in a .po file by a pair of lines as shown below:

msgid "Name"
msgstr "Имя"

We recommend using English strings as localization keys. This will allow your application to have a fully functional web interface in English. If translations of some or all interface strings are missing, then their English keys will be displayed in a browser.

Multiple forms of localization strings

Multiple translation forms allow an application developer to easily display localization strings in the correct form depending on the context, if it is required by the rules of a specific language; e.g. (there are several plural forms of the Russian word запись = record): 21 запись, 22 записи, 25 записей.

The following code in the header of a .po file is used to specify that there are three plural forms in the Russian language (as shown in the above example) and contains a formula to determine the correct plural form of a word depending on the number used with that word:

"Plural-Forms: nplurals=3; plural=((((n%10)==1)&&((n%100)!=11))?(0):(((((n%10)>=2)&&
((n%10)<=4))&&(((n%100)<10)||((n%100)>=20)))?(1):2));\n"

A translation example of multiple word forms in a .po file:

msgid "post"
msgid_plural "posts"
msgstr[0] "запись"
msgstr[1] "записи"
msgstr[2] "записей"

To obtain the desired localization form for a word in PHP code, use the following syntax:

// this code will return one of the values запись, записи, or записей depending
  on the value of $n in accordance to the formula contained in the .po file
_w('post', 'posts', $n);

Below is shown a similar structure for use in Smarty templates:

{_w('post', 'posts', $n)}

Note the difference between the above example for Smarty and the syntax used to display single-value localization strings in template files: for single-value strings syntax [`word`] should be used.

Function _w() is also capable of automatically replacing substring %d by the value of $n within the translated string using PHP function sprintf; e.g.:

_w('%d file', '%d files', 21); // 21 файл (Russian for "21 files")
_w('%d file', '%d files', 22); // 22 файла (Russian for "22 files")
_w('%d file', '%d files', 25); // 25 файлов (Russian for "25 files")

Automatic generation of .po files

The framework supports automatic analysis of the entire source code of an application in order to collect all localization keys and to append missing keys to the .po file. If there is no .po file for an application, it is created automatically. To launch the automatic .po file generation scripts, run the following command on your server:

Example

php wa-system/locale/locale.php myapp

Auto-generation of .po files for plugins is performed in a similar way:

php wa-system/locale/locale.php [APP_ID]/plugins/[PLUGIN_ID]

Example

php wa-system/locale/locale.php myapp/plugins/some

Note: The current version of the localization file generation script does not support multiple string forms; therefore, such strings should be manually added to a .po file.

Localization of app plugins

To use plugins' own localization files in PHP code, use function _wp() instead of _w().

Plugin localization files must reside, like those of apps, in locale/[LOCALE]/LC_MESSAGES/ inside plugin's subdirectory, and their names must match rule [app_id]_[plugin_id].po and [app_id]_[plugin_id].mo. For example, a Russian localization .po file of some plugin with ID some for the shop app must be available at wa-apps/shop/plugins/some/locale/ru_RU/LC_MESSAGES/shop_some.po (a .mo file must be located in the same directory).

Localization of system plugins

Names of localization files used for system plugins, which are located in wa-plugins/ directory, must have a suffix matching plugin's type, i.e. payment_, shipping_, or sms_. Here is an example of a Russian localization .po file of some payment plugin with ID some: wa-plugins/payment/some/locale/ru_RU/LC_MESSAGES/payment_some.po

To include localization strings of your plugin in its source code, use public method _w() of base class waSystemPlugin as shown in the examples below:

Development of a single-locale product

If you are absolutely sure that your product, an app or a plugin, will be used only with one language locale, then you do not need to use the localization mechanism. In this case simply type localization strings directly in the source code. Functions _w(), _wp(), and [``] constructs should not be used in such a product.