Table of Contents

Translate ispCP

If you've translated Unix/Linux applications before, you might already know the GNU gettext tool library. If you do so, you can immediately start translating by using the .po files in the languages-files directory.
If you are new to the GNU gettext tool library and concepts, read on.

How comfortable the new way is

ispCP is currently translated using the GNU gettext tool library. Strings are directly edited in the source code, and extracted after the development so translators can directly translate the strings.

In the past, we have had so-called language variables. However, this system had a few drawbacks. Every time a new string was added, modified or removed in ispCP, developers had to create a new language variable which afterwards had to be translated.

How to translate

When the development of a new ispCP version has been finished, developers extract all strings using a special tool into so-called language files. These files can be found in the directory ./language-files/. All files with at least one translated line are located under their 639-1 ISO Language Codes. All codes can be found under http://www.loc.gov/standards/iso639-2/php/code_list.php

If you open a .po file, you'll see the default messages and their translation:

#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-07-06 16:02-0500\n"
"PO-Revision-Date: 2007-07-06 16:02-0500\n"
"Last-Translator: FULL NAME \n"
"Language-Team: English \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
"X-Generator: x64PoPot 0.2\n"

#. Please ignore this entry
msgid "encoding"
msgstr "UTF-8"

msgid "_: Localised language"
msgstr "English"

msgid "ISPCP - Virtual Hosting Control System"
msgstr ""

You can ignore the very first lines, as they are not important for translation, however you can add your personal infos to show anyone, you've translated the file and the credits go to you.

The important lines are “msgid” and “msgstr”.
The “msgid” specifies the source text, and the “msgstr” the translation. Thus, it's very easy to translate as you always see the original text and your translation.
You can also use poEdit which is a graphical front end to .po files and available for both Linux and Windows (note that other editors like KBabel work just fine).

How to upload your translation into ispCP

After you complete your translation using your favourite .po editor, you have to convert your .po file to A=B format.
You can do it by using the online poconverter tool here:
Online .po converter
You will get back a file, which is used to upload it to your ispCP Admin Panel, under the Internationalization submenu.
Make sure, your file name was xx_XX.po format before uploading to the online converter, for example: hu_HU.po or en_GB.po. Any other case you will be not able to upload and you will get an error message.

Understanding the header of the .po files

The header of a po file contains some useful and important information for gettext and the translations converter.

The first lines of the header can be skipped:

#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-07-06 16:02-0500\n"
"PO-Revision-Date: 2007-07-06 16:02-0500\n"
"Last-Translator: FULL NAME \n"

The above fields are usually updated automagically by the po editor.

Specifying the language:

"Language-Team: English \n"

This header entry must contain the language name in English.

An example is:

"Language-Team: Spanish (Mexico) \n"''

Note that the email address is not important, but both, the language and the country names are very important. Even tough the country name is not really required it is very very recommended to be set in case somebody else translates ispCP in the same language but making use of regionalisms.

"MIME-Version: 1.0\n"

This entry can be safely skipped.

"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"

The first two entries are important in case you are not using UTF-8 in your translation (it is very recommended to use UTF-8 tough).
The last entry is not currently being used, but might be used when plurals support is added to the translations converter and to the internal translations handler in ispCP. To read more about plurals check the gettext manual

Understanding other stuff you will find in the po files

In order to make it easier for translators ispCP's translation system makes use of conversion specifications. What are these? these are tokens that are replaced by, usually but not only, numbers or any kind of scalar value.
Let's see an example:

#, php-format
msgid "You have %d new support questions"
msgstr "Tienes %d nuevas preguntas de soporte"

In this example the token %d is replaced with the number of support questions. These tokens lets the translator put the number of support questions at any place in the sentence.
A very easy to understand example is:

#, php-format
msgid "You have %d new support questions"
msgstr "The number of new support questions you have is: %d"

What would happen if there are more than one tokens that are being replaced and the order is changed?
This situation is also very nicely handled by ispCP:

#, php-format
msgid "%1$.2f %% [%2$d of unlimited]"
msgstr "%1$.2f%% [%2$s de ilimitados]"

If you notice in this example there are three % tokens, but only two are replaced. The double sign (%%) one is only replaced with a percent sign. Also, in this example you will notice that every % token that will be replaced is followed by a number, then a dollar sign and finally a letter.
The number following the percent sign is the identifier of the token, so in case you first need/want to display the content of the second token and then the first one it is possible.
For more information on these tokens check this page.
Also, all the lines in the po file that begin with a # symbol are comments; some of these are important and should not be deleted/modified.
Time by time the messages that need to be translated are modified and the old messages instead of just being discarded they are kept at the end of the po file.
An example of these old messages is:

#~ msgid "suspended"
#~ msgstr "suspendu"

#~ msgid "enabled"
#~ msgstr "activé"

These ones can be safely removed as they are only kept so the translator may rescue some of those messages and adapt them to their needs.

How to syntax-check the Translation

You can test your translation by running the application “msgfmt”:

msgfmt LANGUAGE.po –o LANGUAGE.mo

You have to replace LANGUAGE with the file name.
This command compiles the textual .po file into a binary one called .mo file. This .mo file is not used by ispCP but it will help you find errors in your translation.

How to test your translation in ispCP

Right before a release is made or when a po file is updated with new translated messages the final translation file is generated.
Meanwhile, if what you want to do is simply test how your translation is going you can use the online converter, which will generate the translations file from the uploaded po file.
After uploading the file the script will generate the final file and prepare it for you so you can download it. When you've done that, all you have to do is add the translations file to ispCP via the GUI.