====== Plugin Localization ====== This page is about plugin localization, i.e. creation of a ''locales'' directory, a sub-directory per language and finally a ''main.po'' file that will contains the plugin translation in one language. ===== Localization files user guide ===== ==== General process ==== Each plugin contains text that must be adaptable for every language and not simply hardcoded in the source code. To achieve this, files with a ''po'' extension are added. Once parsed by Dotclear2 engine, these files will replace codes like by the word or the sentence in the blog language. To do this, the plugin must have a translation in the given language. You will find below the detail of all the files used. ==== Files organization ==== === The locales directory === The directory named **locales** contains one sub-directory per language the plugin is translated in. For instance it can contain: * an **en** directory that will contain the English translation files * an **es** directory that will be for the Spanish version (optional) * etc. ==== The main.po file ==== Localization example: # French translation of DotClear # Copyright (C) 2006. # Olivier Meunier , 2006. # msgid "" msgstr "Content-Type: text/plain; charset=UTF-8\n" ... #: plugins/maintenance/index.php:74 #, php-format msgid "Indexing entry %d to %d." msgstr "Index des billets %d à %d" ... The three first lines contain the translator comments: * The translation language, * The license associated to the file, * The author's name and e-mail address as well as the date of translation. Let's break down this piece of code to define the use of each line: msgid "" msgstr "Content-Type: text/plain; charset=UTF-8\n" These two lines define the file format as well as the character encoding method. Here it's using text type and UTF-8 enconding. For more information on encondig: [[http://www.w3.org/International/O-HTTP-charset.en.php|W3C website]] #: plugins/maintenance/index.php:74 This line indicates in which file the translation is used and in which line of that file it is used. If the same translation is used several times, you just have to indicate all the lines like in the following example: #: plugins/maintenance/index.php:87 plugins/maintenance/index.php:111 If it is really used a lot, you can also use the following syntax that fits on several lines: #: inc//core/class.dc.blog.php:1497 inc//core/class.dc.blog.php:1503 #: inc//core/class.dc.blog.php:1565 msgid "No such comment ID" msgstr "Identifiant du commentaire inconnu" Optionally, you can indicate that the translation contains PHP variables: #, php-format In this case, the %d is an integer PHP variable: msgid "Indexing entry %d to %d." There are other types of variables. For instance to pass a string, you'll have to use **%s** instead of **%d**. For more information on variables and how to use them, please refer to the [[http://php.net/manual/en/function.sprintf.php|PHP sprintf function documentation]]. The **msgid** keyword associates a unique identifier to the translation. It is therefore important never to have the same identifier referring to two different translations. msgstr "Index des billets %d à %d" Finally the **msgstr** keyword contains the translation. If we have a look at the index.php file, line 74... err 90 ;-): echo '

'.sprintf(__('Indexing entry %d to %d.'),$start,$start+$limit).'

';
Voici donc l'appel de la traduction. À la place de "%d to %d", elle contiendra le contenu des variables **$start** et **$start+$limit**. Here is where the translation is called. The two ''%d'' will be replaced by the content of **$start** and **$start+$limit** variables, respectively. As this example shows, the comment regarding the translation line is not correct anymore, many lines seems to have been added in the index.php file of the plugin. It is important to update the translation files when the plugin files containing texts to be translated are modified. Please also note that: * the **msgid** keyword cannot end with a space. For instance, "My string" will be found and replaced by its translation, but not "My string ". * there is a shell script to create a template, please check [[http://dev.dotclear.org/2.0/browser/locales/po_update.sh|po_update.sh]] * there is a translation plugin called [[http://lab.dotclear.org/wiki/plugin/translater|Translater]] ==== The public.po file ==== It is created the same way as the main.po file and will translate the strings that appear on the public side of the blog. Do not forget to add **l10n::set(dirname(__FILE__).'/locales/'.$_lang.'/public');** in the theme/plugin **_public.php** file. ===== Exceptions for some plugins ===== Some plugins prefer the old methods used on Dotclear 1 or to mix both methods. These methods **should not be used**, therefore we'll only see them quickly. ==== The Dotclear 1 method ==== Peut être dans le but d'une adaptation rapide vers Dotclear2 tel que le plugin newsletter, Might have been done in order to quickly migrate to Dotclear 2, such as the [[http://lab.dotclear.org/wiki/plugin/newsletter|newsletter plugin]]. === The main.lang.php file === Same principle as Dotclear 2 except everything is on the same line and we don't know what files are calling it. $GLOBALS['__l10n']['Newsletter'] = 'Lettre d\'informations'; Les fichiers ''*.lang.php'' sont traités plus rapidement que les fichiers ''*.po''. Il est possible de créer les traductions dans un fichier ''.po'' puis de générer un fichier ''.lang.php'' correspondant. The ''*.lang.php'' files are parsed faster than the ''*.po'' files. It is possible to put the translations in a ''.po'' file then to generate the corresponding ''.lang.php'' file. ==== Dotclear 1 & 2 method ==== Some plugins use both ''main.po'' and ''main.lang.php'' files. The ''main.lang.php'' file has the priority over the ''main.po'' file. If one of those is not available Dotclear 2 will chose the other, but by default it will use ''main.lang.php''. ==== No translation ==== Some plugins do not use any files. Avoid this at all cost!