Aventures dans l'internationalisation, épisode 2

Sébastien Aperghis-Tramoni
sebastien@aperghis.net

Avertissement

  • je n'y connais toujours rien

    • ou presque

Terminologie

  • I18N : internationalisation

  • L10N : localisation

Présentation

  • I18N de ProductOpener

  • la partie serveur de OpenFoodFact / OpenBeautyFacts

État des lieux 2016

  • OpenFoodFact / OpenBeautyFacts

  • localisés dans 10-20 langues

  • certaines langues à 100% : français, anglais, allemand, italien, espagnol, grec, hébreu...

  • d'autres bien moins : russe, japonais, arabe, chinois...

  • présence symbolique : indonésien, gallois, hongrois...

État des lieux 2016

  • problème : contribuer une localisation est complexe

  • fichiers dans wiki

  • tailles importantes, fait planter l'éditeur de wiki

  • en réalité, du code Perl

Solution

  • migrer vers des fichiers .po

  • format standard

  • logiciels et plates-formes conçus pour

    • POEdit, Lokalize, Transifex, Zanata, Launchpad

  • facile de contribuer une localisation

Plan

  • ◻︎ 1. convertir les hashes en fichiers .po

    • trivial

he.po

 msgid "Add a product"
 msgstr "הוספת מוצר"
 
 msgid "Register"
 msgstr "הרשמה"
 
 msgid "Take a picture"
 msgstr "צילום תמונה"
 
 msgid "Barcode"
 msgstr "ברקוד"
 
 msgid "Ingredients list"
 msgstr "רשימת רכיבים"
 
 msgid "Product without barcode"
 msgstr "מוצר ללא ברקוד"
 
 msgid "Origin of ingredients"
 msgstr "מקור הרכיבים"

ar.po

 msgid "Add a product"
 msgstr "إضافة منتج"
 
 msgid "Register"
 msgstr "التسجيل"
 
 msgid "Take a picture"
 msgstr "التقاط صورة"
 
 msgid "Barcode"
 msgstr "الباركود"
 
 msgid "Ingredients list"
 msgstr "قائمة المكونات"
 
 msgid "Product without barcode"
 msgstr "المنتج دون الباركود"
 
 msgid "Origin of ingredients"
 msgstr "أصل المكونات"

ja.po

 msgid "Add a product"
 msgstr "製品を追加"
 
 msgid "Register"
 msgstr "登録"
 
 msgid "Take a picture"
 msgstr "写真を撮ります"
 
 msgid "Barcode"
 msgstr "バーコード"
 
 msgid "Ingredients list"
 msgstr "成分リスト"
 
 msgid "Product without barcode"
 msgstr "バーコードのない商品"
 
 msgid "Origin of ingredients"
 msgstr "成分の起源"

Plan

  • 1. convertir les hashes en fichiers .po

  • ◻︎ 2. utiliser les fichiers .po

    • plusieurs modules existent

    • Locale::Maketext::Lexicon, utilisé dans Act

Exemple

  package OpenFoodFacts::I18N;

  use Locale::Maketext::Lexicon;
  use parent "Locale::Maketext";

  Locale::Maketext::Lexicon->import({
      '*'     => [ Gettext => 'po/*.po', ],
      _auto   => 0,
      _decode => 1,
      _style  => 'gettext',
  });


  package main;

  my $i18n = OpenFoodFacts::I18N->get_handle("fr");
  say $i18n->maketext("Add a product");

En pratique

  • mais utilisation des hashes dans le code

  • $Lang{products}{$lang}

  • $Lang{$ranktype . "_p"}{$lang}

  • $Lang{$class . '_' . $ingredients_classes{$class}{$icid}{level} }{$lang}

Plan

  • 1. convertir les hashes en fichiers .po

  • ◻︎ 2. utiliser les fichiers .po

    • conserver les hashes

      • soit avec de la magie (tie)

      • soit par reconstruction

    • utilisation des chaînes anglaises

      • garder les clés d'origine des hashes

      • stockées comme msgctxt dans les .po

he.po

 msgctxt "add_product"
 msgid "Add a product"
 msgstr "הוספת מוצר"
 
 msgctxt "add_user"
 msgid "Register"
 msgstr "הרשמה"
 
 msgctxt "app_take_a_picture"
 msgid "Take a picture"
 msgstr "צילום תמונה"
 
 msgctxt "barcode"
 msgid "Barcode"
 msgstr "ברקוד"
 
 msgctxt "ingredients_text"
 msgid "Ingredients list"
 msgstr "רשימת רכיבים"
 
 msgctxt "no_barcode"
 msgid "Product without barcode"
 msgstr "מוצר ללא ברקוד"
 
 msgctxt "origins_s"
 msgid "Origin of ingredients"
 msgstr "מקור הרכיבים"

ar.po

 msgctxt "add_product"
 msgid "Add a product"
 msgstr "إضافة منتج"
 
 msgctxt "add_user"
 msgid "Register"
 msgstr "التسجيل"
 
 msgctxt "app_take_a_picture"
 msgid "Take a picture"
 msgstr "التقاط صورة"
 
 msgctxt "barcode"
 msgid "Barcode"
 msgstr "الباركود"
 
 msgctxt "ingredients_text"
 msgid "Ingredients list"
 msgstr "قائمة المكونات"
 
 msgctxt "no_barcode"
 msgid "Product without barcode"
 msgstr "المنتج دون الباركود"
 
 msgctxt "origins_s"
 msgid "Origin of ingredients"
 msgstr "أصل المكونات"

ja.po

 msgctxt "add_product"
 msgid "Add a product"
 msgstr "製品を追加"
 
 msgctxt "add_user"
 msgid "Register"
 msgstr "登録"
 
 msgctxt "app_take_a_picture"
 msgid "Take a picture"
 msgstr "写真を撮ります"
 
 msgctxt "barcode"
 msgid "Barcode"
 msgstr "バーコード"
 
 msgctxt "ingredients_text"
 msgid "Ingredients list"
 msgstr "成分リスト"
 
 msgctxt "no_barcode"
 msgid "Product without barcode"
 msgstr "バーコードのない商品"
 
 msgctxt "origins_s"
 msgid "Origin of ingredients"
 msgstr "成分の起源"

Problème

  • gettext ne permet pas de chercher par msgctxt

  • seulement par msgid

Locale::Maketext::Lexicon::Getcontext

  • variante expérimentale de Locale::Maketext::Lexicon::Gettext

  • pratiquement un copié-collé avec s/msgid/msgctxt/g

  • peut-être une mauvaise idée

  • mais permet d'utiliser plus simplement les .po dans ProductOpener

Plan

  • 1. convertir les hashes en fichiers .po

  • 2. utiliser les fichiers .po

  • 3. profit!

État des lieux 2017

  • Locale::Maketext::Lexicon::Getcontext publié sur le CPAN

  • utilisé dans ProductOpener

  • branche correspondante fusionnée

  • fichiers .po mis sur Launchpad

  • code source des différents logiciels mis sur GitHub

État des lieux 2017

  • contribution aisée

  • localisation dans environ 60 langues

Conclusion

Questions ?

Merci