What is required from developers to get Phabricator translatable.
Developers are supposed to call pht() on all strings that require translation.
Phabricator provides translations for this translator through PhabricatorTranslation class.
Adding a translation which uses the same language rules as some already existing translation is relatively simple: Just extend 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 language involves all steps as adding a translation plus specifying the language rules in PhutilTranslator::chooseVariant().
Different languages have various rules for using singular and plural. All you need to do is to call 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 pht() will remain in the text only if the translation doesn't exist.
Different languages use different words for talking about males, females and unknown genders. Callsites have to call pht() passing PhabricatorUser (or other implementation of 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');