Internationnalisation (i18n)

Galette source code is entirely internationnalised thanks to GNU Gettext. All translatable strings in the source code must be in english.

The lang directory contains:

  • Makefile, make_lang_l12n.py, xgettext.py: utilities to manage translations,
  • *.pot: transaltions template files, one per domain,
  • *.po: translation files, one per lang and per domain.

Galette core, all oficial plugins as well as documentations are translated using Weblate platform.

Syntax

Two different types of syntax are used:

  • PHP syntax,
  • Smarty syntax.

PHP

For PHP syntax, this is the _T function that is used. There is a second optionnal argument for translation domain, which defaults to galette.

<?php
echo _T("Hello world!");
echo _T("Hello world!", "galette"); //galette is the default domain
?>

Note

Another method, __() is very similar to _T(). This one will not mark strings which miss a translation.

This was used to translate routes mainly; but this is no longer possible.

Often, you will have to use variables in translated strings. To do that, use a placeholder in the string to translate, and use something like str_replace or preg_replace to do the effective replacement:

<?php
echo str_replace('%name', $adh->name, _T("Hello %name!"));
?>
<?php
$search = array(
   '/%name/',
   '/%surname/',
   '/%town/'
);
$replace = array(
   $adh->name,
   $adh->surname,
   $adh->town
);
echo preg_replace(
   $search,
   $replace,
   _T("Hello %name %surname from %town")
);
?>

Note

You can use any word you want as pattern, just try to keep simple for others :) There are several other ways to handle string replacements, check PHP documentation.

Smarty

Smarty translation is done with a custom plugin:

<p>{_T string="Hello world!"}</p>
<p>{_T string="Hello world!" domain="galette"}</p>

Smarty comes with modifiers that may be used to do remplacements among others. But it is done before the text is sent to the plugin, so translation cannot be found (it already contains a replacement value for our pattern). Our Smarty plugin can take two optionnal arguments to handle properly replacements:

<p>{_T string="Hello %name!" pattern="/%name/" replace=$adh->name}</p>

Translation domains

New in version 0.9.

Galette uses translation domains to prevent string replacements from external sources. Default domain name (implicit if not specified) is galette

Each plugin will come with at least one domain of its own.

You must then tell the functions which domain you want to use:

<?php
echo _T('Hello, you'); //uses default domain, french will be 'Bonjour, vous'
echo _T('Hello, you', 'another'); //use another doamin ; french will be 'Salut, toi'

Same example, with Smarty:

{_T string="Hello, you!"}
{_T string="Hello, you!" domain="another"}

Generate lang files

There are several steps to update Galette translations:

  • extract strings from source code and update translation templats (POT files) (run make extract from lang directory and commit updated POT file),
  • (let translators do their job)
  • retrieve translated files (PO) from translation platform
  • compile translation files (MO)

Note

It is possible to generate local PO files with make po, but all mecanisms assume the translation platform is used.

Once the updated POT file has been pushed to the Github mirror, an update is triggered on the Weblate platform. Weblate translations are commited in a forked Git repository, and must be merged back to Galette:

$ git remote add weblate https://hosted.weblate.org/git/galette/galette/
$ git fetch weblate
$ git merge weblate/develop

Finally, you must compile translations (compiled files are the ones used):

$ make mo

In order to refresh known languages, you will have to logout/login from your Galette instance. You may have to restart PHP as well.