@title Internationalization
@group contrib

What is required from developers to get Phabricator translatable.

= API =

Translator API is provided by libphutil. It gives us
@{class@libphutil:PhutilTranslator} class and global @{function@libphutil:pht}
function built on top of it.

Developers are supposed to call @{function@libphutil:pht} on all strings that
require translation.

Phabricator provides translations for this translator through
@{class:PhabricatorTranslation} class.

= Adding a New Translation =

Adding a translation which uses the same language rules as some already existing
translation is relatively simple: Just extend @{class:PhabricatorTranslation}
and you will be able to specify this class in the global configuration
'translation.provider' and users will be able to select it in their preferences.

= Adding a New Language =

Adding a language involves all steps as adding a translation plus specifying the
language rules in @{method@libphutil:PhutilTranslator::chooseVariant}.

= Singular and Plural =

Different languages have various rules for using singular and plural. All you
need to do is to call @{function@libphutil:pht} with a text that is suitable for
both forms. Example:

  pht('%d beer(s)', $count);

Translators will translate this text for all different forms the language uses:

  // English translation
  array('%d beer', '%d beers');

  // Czech translation
  array('%d pivo', '%d piva', '%d piv');

The ugly identifier passed to @{function@libphutil:pht} will remain in the text
only if the translation doesn't exist.

= Male and Female =

Different languages use different words for talking about males, females and
unknown genders. Callsites have to call @{function@libphutil:pht} passing
@{class:PhabricatorUser} (or other implementation of
@{interface@libphutil:PhutilPerson}) if talking about the user. Example:

  pht('%s wrote', $actor);

Translators will create this translations:

  // English translation
  '%s wrote';

  // Czech translation
  array('%s napsal', '%s napsala');
