Table of Contents
As of ZeroBin 0.21 translations are available and PrivateBin is no longer English only.
The translation concept follows similar concepts as GNU gettext:
- Each language has a translation file containing all its translated texts.
- As message IDs we use the original sentences in English. Therefore any untranslated messages will fall back to English and no English translation files need to be added.
- Plural forms are supported.
TL;DR: How to translate
- Go into the directory
i18n
. - Copy one of the files into your languages two-letter ISO 639-1 code, i.e. to
es.json
for a Spanish. - Open the file in a text editor and change the messages after the english message ID.
- Save the file in UTF-8 character encoding.
- Add your new language code into the array called
supportedLanguages
injs/privatebin.js
(around line 300). - (optional) As you modified the JavaScript file you have to update the SRI hashes too. If you do not manage this, you may also just leave this task to the maintainers, who can do this for you when merging the PR.
- Done. Now you can create a pull requests to get your translation merged into the official PrivateBin.
Technical Details
Format
As PrivateBin has to provide a logic for both the server and the client side, the format of choice is JSON. You find these files in the directory i18n
; They have to be accessible through the webserver.
Each translation file is saved under the name of the languages two-letter ISO code and contains one JSON object. The attributes of the object are the message IDs to be translated from English and the values stored in them are the translated strings.
Dynamic values
Often a dynamic value should be inserted into the message. In these cases the message IDs will be ideally full sentences, as the position of these values might change in different languages. The dynamic values are marked by either %s
for strings or %d
for numbers in the message ID.
Plural forms
Many languages use plural forms and some even more then one. For number dependent messages, an array of strings instead of a string can be set in the value of an attribute. Each language has a rule to decide which element from the array to use, given a certain number. Most languages will have the singular in the first position and the plural in the second. Here is an example for French:
{
[...]
"%d seconds": ["%d seconde", "%d secondes"],
[...]
}
Some languages can have more then one plural forms. Which form to use depending on a given number is decided based on a formula.
Gotchas
Currently we do not inform the JS part about the available languages on the server, but instead these are statically encoded in the file js/privatebin.js
in the property i18n.supportedLanguages
(around line 300). If you add a new language, remember to add it there, too.
If your new language does use more complex plurals then English, you need to add the formula for it in two places:
- lib/I18n.php in class i18n, method _getPluralForm()
- js/privatebin.js in class i18n, method getPluralForm()
For the language labels displayed in the optional language selection drop down menu, a file called i18n/languages.json
was created. Most languages should already be included with a translated language label and its English translation.
If you provide translations for one of the languages not included in the list, you need to add it in there. Create a new property with a (not yet existing) ISO code and the language labels in its native form and translated to English, as in the example below:
{
[...]
"qp": ["tlhIngan Hol", "Klingon"],
"13": ["1337 5934|<", "Leetspeak"],
[...]
}