Translation Guide

We are looking for translators. If you want to see WIKINDX in your native language do not hesitate to join us on Transifex.

If you only want to report an error without committing yourself to fixing it, post it on the forum or the wikindx-developers mailing list.

Introduction

This document is intended for developers and translators of WIKINDX.

WIKINDX has a translation system for its graphical interface, bibliographic styles and plugins. It uses :

Before 6.6.0 Gettext was used but never worked on Mac.

You need only a PHP CLI and a Transifex Account.

Localisation (l10n)

Translation is, in fact, about localisation (l10n) in the broad sense because other elements can be adapted according to time, place, language, culture, etc.

For example, the sort order and the date format will change according to user’s preference. Language itself is only one aspect.

In order to be able to replace the original messages (in English) while running, WIKINDX needs a catalog of messages translated by linguistic variant and by domain (see below).

Translating

The latest version of official messages to translate is online on Transifex, a translation project management system.

Messages from unofficial plugins are not on this platform. It is up to their author to ensure the translation. In the following we will only speak for the case of a translation of core messages or official plugins.

Before your first contribution, register for free on this portal.

Then go to the languages section of the WIKINDX project. Choose the language of translation, for example, French (fr).

The code in parenthesis is called a locale. It denotes a language (ll) (without national preference) or a language and a country (ll_CC) or a language, a script, and a country (ll_Script_CC]).

For example, the translation catalog of the locale fr will be automatically used for the locales fr_BE, fr_CA, fr_CH, fr_FR, fr_LU, fr_MC as long as they do not have their own catalog of translations.

If the language you want to translate does not yet exist, make a request to the WIKINDX developers to add it. A discussion might be needed to decide the most appropriate code for your translation.

On the language screen you see the catalog files listed by domain (Transifex calls this a resource): adminstyle.php, backupmysql.phpwikindx.php is the main file. It contains the translation of the core. The other files are the plugin translations (one file per plugin). Translate wikindx.php first, because it benefits the largest number of users.

Click on a catalog, a popup opens. You can see the number of messages to translate, to review, or that are already translated.

You can either translate online on the Transifex portal or download the catalog file and translate it with a text editor, uploading it when finished to the translated file on the portal.

When you are working alone you can choose one of the above working methods, but, when several people work at the same time on a translation, you should not use the file upload method unless you coordinate with others because, when uploading back to the portal, messages uploaded by other users are overwritten. For the same reason, when working with others, it is not a good idea to keep a file outside of Transifex for a long time (several days or weeks).

Click on the Translate button. Now, you are in the translation screen.

On the left is a list of messages (without duplication, unless it is voluntary) sortable, and filterable at will.

In the center is the translation area and additional information about a message that can help you translate it. You can see from which file the message is pulled and sometimes a comment left by a developer to specify the context.

On the right there are translation suggestion tools, a translation history and so on.

Translate the strings one by one. When you select a message with the checkbox on the list on the left you can also display the automatic translation option. The automatic translation is approximate and does not exempt you from making all the corrections necessary for a good understanding of the text.

You can also mark them when you have proofread them. As long as a message is not translated, its English version will be displayed instead. This allows WIKINDX to use a partially translated catalog even if a complete translation is not yet available for users.

When compiling the translation, other than a finished translation, there are 6 major scenarios for each message:

  • The message is not translated, lacks a suggestion, and its translation is different in your language: just translate;
  • The message is not translated and its translation is identical in your language: copy and paste the English version;
  • The message is not translated, has a suggestion, and its translation is different in your language: When developers update the model catalog, the new strings to translate are automatically added to the list. If an original message has changed or looks like another, its translation is requested again with a suggestion in the right pane. It’s up to you to decide whether the translation needs to be rewritten completely or if the suggestion is reusable;
  • You have been notified of, or you notice, a translation error: find the message and correct its translation;
  • You think you have found an error in an English message: do not translate and report it by email to the developers so that the English can be checked. If the error is minor (like a missing plural) and does not affect the possible meaning of the translation you can still translate with the meaning that you deem correct. If the English is corrected later the message will be marked for proofreading;
  • If you cannot translate a message or your translation would be incomplete, do not translate it at all, leaving the translation empty.

Some messages contain code and variables like $QUICKSEARCH$ that you do not have to translate. Others contain placeholders such as #currentWikindxVersion#, ### (WIKINDX specific syntax), and %s, %d, %1$s, %2$s (see the printf function family for a complete description). You should not change these placeholders because they are replaced by numbers, dates, and strings (the replacement value should be described in the comment of the message). You can, though, change their position in a translated message if there is only one in a message, or if they have an index like %1$s, %2$s.

Currently, the messages have not been written with regard to translating them in a language that is written from right to left or fully repositioning the placeholders.

Unless there are special instructions in the comments you can change the rest of the message including typography for a better layout. You also have the capabilities of UTF-8 so do not use an HTML entity – rather input the character directly.

When you have finished translating the domains, report it to the WIKINDX developers so that it is integrated into the core software as soon as possible. As a general rule, share your intentions or difficulties with the developers or coordinators of your language. We can help you.

For translation difficulties and help resources you can contact groups of translators of your languages as indicated on this page of the Translation Project.

Using or testing a new translation

You have completed the translation (or translated more than 50% of messages) and you want to test the result.

In the core/messages/src directory of your WIKINDX installation, create a folder named with the locale code for the new language in lowercase (each plugin has also its own folders). For example, create a sl code for Slovenian or pt_BR for brazilian Portuguese. Do the same thing for each plugin if you have a file for it.

Unless your language needs to be specified as a script or region of a language that already exists use the language part of the code only. If in doubt, ask the core developers.

Open a console, chdir to the WIKINDX installation directory and run the cli-make-translations.php script.

$ cd /my/wikindx/directory
$ php cli-make-translations.php

If all goes well, this script will create a subdirectory named core/messages/cat and PHP files inside it for each locale. These files are the final data format of translations used by WIKINDX runtime.

It does the same thing in components/plugin/<id>/messages/cat folder of each plugin. <id> id the id / root folder name of a plugin. Following description about the core translation works the same way for plugins.

Others subdirectories (core/messages/src/<ll_Script_CC>) contain translation catalogs. This data format is used to prepare translation.

Example of translations tree:

core/messages
 |_ cat
 |  |_ ..
 |  |_ de.php             <= compiled translation messsages
 |  |_ pt_BR.php
 |  |_ sl.php
 |  |_ ..
 |_ src
 |  |_ wikindx.php        <= messages extracted by WIKINDX
 |  |_ de
 |  |  |_ wikindx.php     <= translated messages
 |  |_ pt_BR
 |  |  |_ wikindx.php
 |  |_ sl
 |  |  |_ wikindx.php
 |  |_ ..
 |_ wikindxMessages.php   <= messages declared by developers

On transifex, download each catalog of your language and copy them into that core/messages/src/<ll_Script_CC> subdirectory.

Execute again the cli-make-translations.php script.

This time, the script extracts the translations from your translation files and turns them into compiled translation catalog files in cat folder. These are in a more suitable format and the only one recognized when running WIKINDX.

Finally, you can choose your language in WIKINDX to see your translation into action.

Packaging and distribution

If you have translated on transifex, your contribution will be distributed with the next version of the core/plugins. If you have translated a PO file directly and want your work to be distributed, contact the developers. In any event, let us know your names and surnames or your nickname, your email and / or website, the license (to be discussed if it is different from that of the core) for the credits.

For non-official plugins, you have to send your translations to the translation developer.

Internationalisation (i18n)

Operation

This is a quick introduction, for full details, read the code.

To update source messages on Transifex, copy the files to the /home/project-web/wikindx/htdocs/transifex/php directory on the SF WIKINDX Website FTP folder. Transifex updates the resources (twice a day) from these files. You can force the update by hand but put the files online before.

Deleting, damaging, or pushing outdated files in the /home/project-web/wikindx/htdocs/transifex/php folder can result in loss of translations when references strings are removed or modified. The same can happen when pushing a file by hand.

Source messages files circulate in the SVN => Transifex direction. And the files of translated messages in the reverse direction. Doing otherwise can result in the loss of translators’ work. It is still possible to load translated files in bulk on Transifex but you must coordinate with the translators to obtain read-only access and synchronization of work in progress before.

One must be very careful with these maintenance operations.

All core reference strings are stored in two-level PHP arrays, the first of which is a thematic grouping key and the second of which is a key for naming the requested string. All these strings are grouped in core/messages/wikindxMessages.php file. The PHP MESSAGES is used as a method of accessing the strings for the entire application.

Under the wood, a custom function \LOCALES\translate_message() takes care of locating the correct translated message in compiled catalog of translations for the whole core without taking into account the sub-key partitioning.

Each message is translated according to the best locale available compared to the user preferred locale. If no translation is found, the original message is returned (correspond to the reference language WIKINDX_LANGUAGE_DEFAULT).

The PLUGINMESSAGES class also offers a method of access to translations for plugins. It requires two conditions:

  • Its domain is the same as its plugin id (e.g. “adminstyle” domain for “adminstyle” plugin).
  • The reference strings are defined in messages/<pluginid>Messages.php file as a function named <pluginid>Messages() and returning an array of string where keys are message ids and value the messages.

core/startup/WEBSERVERCONFIG.php script is responsible for calling the \LOCALES\load_locales() function which loads the translation catalogs into memory according to the preferences of the user session. Catalogs of only one language can be loaded at the same time. The catalog closest to the desired locale is loaded, if there is one, examining the script, then the country, and finally the language.

\LOCALES\getAllLocales() provides a prebuilt list of locales selected from Intl, in the hope that it is as complete as possible. Their names (language + country name) are in the locale language itself for easy user access. Users choose their preferred locale from this second list.

An artificial locale called auto is added to this list. It allows the user to let WIKINDX deduce its locale from the headers sent by its browser.

The language code returned in the HTML source code of pages IS NOT a locale but that which corresponds to it in the BCP47 encoding.

Catalog formats

Catalog of original messages for WIKINDX

These files are array of english strings embedded inside a function called <domain>Messages().

There are stored as core/messages/<domain>Messages.php and components/plugins/<pluginid>/messages/<domain>Messages.php files.

Here is the example of the core catalog (always two level of keys):

<?php
function wikindxMessages()
{
	return array(
// translators:
// Page headings
	    "heading" => array(
			"configure" => "Configure Wikindx",
			"logon" => "Logon",
			"list" => "List Resources",
			"search" => "Search Resources",
			"select" => "Select Resources",
			"addToBib" => "Add selected to bibliography",
			"addToCategory" => "Add selected to categories",
			"addToSubcategory" => "Add selected to subcategories",
			"addToKeyword" => "Add selected to keywords",
			"addToUserTag" => "Add selected to user tags",
			"addToLanguage" => "Add selected to languages",
			"newResource" => "New Resource",
			"editResource" => "Edit Resource",
		),
	);
}

Here is the example of the backupmysql plugin catalog (one level of keys only):

<?php
function backupmysqlMessages()
{
    return [
        "menu" => "Backup Database",
        "heading" => "Backup Database",
        "backup" => "Backup",
        "noWrite" => "cache/plugins/backupmysql/ is not writeable by the web server user.  It currently has the permissions: ###",
        "deleted" => "Files deleted",
        "newFileName" => "New file name",
        "rename" => "Rename file",
        "renamed" => "File successfully renamed",
        "invalidChars" => "Invalid characters will be removed: #%&{}\\<>*?/$!'\":@+`|=",
    ];
}

Catalog of source and translated string for Transifex

These files associate hashs of English messages one by one with their message in english or the translation language. The exact format is described as a PHP Alternative Array Files.

There are stored inside core/messages/src folders. The english original version is in the foot folder (core/messages/src/<domain>.php or components/plugins/<pluginid>/messages/src/<domain>.php). The translated versions are in subfolders named by locale code (core/messages/src/ll_Script_CC/<domain>.php or components/plugins/<pluginid>/messages/src/ll_Script_CC/<domain>.php).

Here is the example of the core French catalog (core/messages/src/fr/wikindx.php):

<?php
$LANG["d5d7b0016d8402a1cff14ebdd19f3d2837815f81"] = "Configuration";
$LANG["37ae775ac82c5b361e92a042deb10f5fe5a8e267"] = "Connexion";
$LANG["88defc59d40e70df72820cb8d9bfc968907a4cca"] = "Liste de références";
$LANG["2838caa16d38cc2839e3186d3bac10d5f2f45cfd"] = "Recherche de références";
$LANG["76cb17f56c48b1e6cee4708134ae8774b6198c72"] = "Sélection de références";
$LANG["752d82f01ff29ca9d2ae8389c5533ea9e6560707"] = "Ajouter la sélection à la bibliographie";
[...]

Catalog of compiled translations for WIKINDX

These files associate hashs of English messages one by one with their message in the translation language embedded inside a function called translation_catalog_<domain>_<locale>().

There are stored inside core/messages/cat and components/plugins/<pluginid>/messages/cat folders.

Here is the example of a French catalog:

<?php
/**
 * Translate a message of 'wikindx' domain and 'fr' locale
 *
 * @param string $reference_string Original message
 *
 * @return string Translated message
 */
function translation_catalog_wikindx_fr($reference_string)
{
    static $translations = array (
  '000813fe8e1a1f650a85db1ba8480f1938b07389' => 'Page d\'accueil',
  '0013df9b552ff0a171be16e51de6a2c8f05c40cd' => 'Empêcher cet utilisateur de modifier ses informations de connexion. Ceci est généralement utilisé pour un invité / utilisateur de test (comme sur la base de données WIKINDX testdrive)',
  '002aa696972872246796723695a80a0b2dfeac0f' => 'Mot de passe de l\'utilisateur de liaison',
  '003e29e44a66f098ae3d4a8587d8f15cd4264334' => 'La base de données ne contient aucune citation',
  '00c8c8120e26466f1b7f3ca385b1efdc864c638e' => 'Langue',
  '00cb9e969425f4b8edfd29e9296459697757f364' => 'Modifier une actualité',
...
}

Limitations

It is up to the user to choose a locale and not a language to benefit from all the culture-related behaviors even if there is no translation for his/her language. It is not possible for the user at the moment to choose different subtypes of locale.

The core does not necessarily exploit all of the localized PHP features to take advantage of user preferences.

Value replacement in translated strings is poor. It should be replaced by numbered patterns and functions from the printf family.

Plural forms are not yet used in all catalogs.

Notes for translators are actually not mirrored on Transifex. See the source code.

So far the strings have not been written taking into account the direction of writing, formats, and other difficulties related to localization.

There is no distinction between the language desired by the user for the graphical interface and the language of the content entered in resources and other data. The data simply have no language at the moment.

The language of bibliographic styles is defined which can contradict a user preference when formatting.

Substantial work is still necessary.

Some resources on the subject: