Aventures dans l'internationalisation

Sébastien Aperghis-Tramoni
sebastien@aperghis.net

Avertissement

  • je n'y connais rien

    • ou presque

Terminologie

  • I18N : internationalisation

  • L10N : localisation

Présentation

  • I18N de OpenFoodFact / OpenBeautyFacts

État des lieux

  • 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

  • problème : contribuer une localisation est complexe

  • fichiers dans wiki

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

  • en réalité, du code Perl

État des lieux

  • trois hashes :

  • %tag_type_singular

    • ~500 lignes

  • %tag_type_plural

    • ~500 lignes

  • %Lang

    • ~10 000 lignes

État des lieux

  • facile de faire des erreurs

    labels_example => {
    	fr => "AB, Bio européen, Max Havelaar, Label Rouge, IGP, AOP, Saveur de l'Année 2012...",
    	en => "Organic", # "Fairtrade USA, Fair trade, TransFair...",
    	el => "Βιολογικό/Οργανικό/Ολοκληρωμένης Διαχείρισης, Δικαίου Εμπορίου, Π.Ο.Π., Π.Γ.Ε, Χωρίς γλουτένη, Ελεύθερο Γενετικών Τροποποιημένων/Non GMO, Βραβείο γεύσης...",
    	es => "Ecológico, Fairtrade-Max Havelaar, I.G.P., D.O.P., Sabor del año 2012...",
    	pt => "Ecológico, Comércio Justo, Sabor do Ano 2012...",
    	pt_pt => "Ecológico, Produto do Ano 2012, sem glúten, ...",
    	ro => 'Bio',
    	it => "IGP, IGT, DOP, Bio, Ecologico, Non OGM, gluten-free",
    	he => "אורגני", "סחר הוגן, מיוצר בישראל",
    	nl => "EKO, Max Havelaar, Label Rouge, Organisch, Glutenvrij, Smaak van het jaar 2012, ...",
    	nl_be => "AB, Max Havelaar, Label Rouge, Organisch, Glutenvrij, Smaak van het jaar 2012, ...",
    	de => "Bio, Fairtrade-Max Havelaar, demeter, vegan, Glutenfrei, ...",
    },

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 msgctx dans les .po

he.po

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

ar.po

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

ja.po

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

Problème

  • gettext ne permet pas de chercher par msgctx

  • seulement par msgid

Locale::Maketext::Lexicon::Getcontext

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

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

  • peut-être une mauvaise idée

  • mais permet d'utiliser plus simplement les .po dans OFF / OBF

Plan

  • 1. convertir les hashes en fichiers .po

  • 2. utiliser les fichiers .po

  • 3. profit!

Questions ?

Merci