lundi 1 avril 2013

Internationalisation avec FuelPHP


FuelPHP est un framework PHP gratuit et open-source, basé sur le PHP 5.3+. Il implémente une architecture HMVC (Modèle-Vue-Contrôleur Hiérarchique) où le contrôleur y joue un rôle central, la vue et le modèle étant complètement séparés (ils ne peuvent donc pas communiquer entre eux). Il offre aussi d'autres fonctionnalités, comme une implémentation RESTful, une analyse syntaxique de modèles, un mapping objet-relationnel (ORM), un paquetage d'authentification et un système de cache entre autres choses. Nous nous concentrerons ici sur la façon dont il gère l'internationalisation dans sa version 1.5.1 de janvier 2013. Le développement de sa nouvelle base de code 2.0 a d'ores et déjà commencé mais la gestion de l'internationalisation devrait y être identique.

Un exemple très simple


Dans cette première approche, nous allons mettre en place du code pour afficher un modèle via un contrôleur (nous court-circuiterons complètement la vue).

Commençons donc avec notre propre contrôleur Controller_Test placé dans fuel/app/classes/controller/test.php. Nous y plaçons un peu de contenu, c'est-à-dire le titre et le contenu textuel du modèle à afficher. La classe View est un encapsuleur d'objet pour les pages HTML contenant du PHP. Sa méthode forge prend trois paramètres : le chemin vers le fichier de la vue (le template, ou modèle), chemin relatif au répertoire app/views (ici, test/template), un tableau associatif de variables et de valeurs PHP ($data), et un paramètre booléen d'encodage (optionnel, passé à true, sa valeur par défaut, indique que nous suivons la directive d'encodage du fichier de configuration app/config/config.php, qui remplace celle du fichier core/config/config.php). L'encodage interne des jeux de caractères est l'UTF-8 par défaut.
class Controller_Test extends Controller
{
    public function action_index()
    {
        $data = array();
        $data['title']   = "Test Page";
        $data['content'] = "Test page content";

        return View::forge('test/template', $data, true);
    }
}
Le modèle fuel/app/views/test/template.php est le suivant :
<!DOCTYPE html>
<html>
<head>
    
    <?php echo $title ?>
</head>
<body>
    
<?= $content ?>
</body> </html>

Langues et paramètres régionaux


La langue par défaut est l'anglais (en), définie dans le fichier de configuration app/config/config.php, qui remplace celle du fichier core/config/config.php. Si vous désirez changer sa valeur en cours d'exécution, il vous suffit d'utiliser l'appel suivant :
Config::set('language', 'fr');
Vous pouvez aussi définir directement les langues et les paramètres régionaux dans le fichier app/config/config.php.
return array(
    'language'           => 'en', // Default language
    'language_fallback'  => 'en', // Fallback language when file isn't available for default language
    'locale'             => 'en_US', // PHP set_locale() setting, null to not set
    'locales'            => array(
        'en' => 'en_US',
        'fr' => 'fr_FR'
    ),
);
  • language est la langue par défaut de l'application
  • language_fallback est la langue qui sera utilisée si celle par défaut n'est pas trouvée
  • locale est le paramètre régional courant, utilisé par la fonction PHP set_locale(). Il peut être mis à null
  • locales sont les paramètres régionaux supportés par l'application. Vous pouvez utiliser le paramètre régional que vous désirez (langue + région), et les forcer à utiliser une langue en particulier
Dans cet exemple, nous avons choisi l'anglais (États-Unis) par défaut, et nous avons ajouté le support du français (France).

Stockage des données sur les langues


FuelPHP prend en charge quatre manières différentes pour stocker les données sur les langues :
  • un tableau PHP :
    return array('key' => 'value');
    
  • un fichier de configuration INI :
    [group]
    key=value
    
  • un fichier de configuration YAML :
    group:
       key: value
    
  • un fichier de configuration JSON :
    {
    "group":
        {
            "key": "value"
        }
    }
    
Nous allons maintenant créer le fichier de langue pour le français app/lang/fr/test.php
return array(
    'test_page' => 'Page de test',
    'penguin' => 'Pingouin',
    'hello' => 'Salut !',
    'hello_name' => 'Salut, :name !',
    'test_group'=> array('hello' => 'Salut à toi, :name.')
);
Et son équivalent en anglais app/lang/en/test.php
return array(
    'test_page' => 'Test page',
    'penguin' => 'Penguin',
    'hello' => 'Hello!',
    'hello_name' => 'Hello, :name!',
    'test_group'=> array('hello' => 'Hello to you, :name.')
);
Le contrôleur fuel/app/classes/controller/test.php est maintenant :
class Controller_Test extends Controller
{
    public function action_index()
    {
        Config::set('language', 'fr');
        Lang::load('test');

        $data = array();
        $data['title'] = Lang::get('test.test_page');
        $data['content1'] = Lang::get('hello');
        $data['content2'] = Lang::get('hello_name', array('name' => Lang::get('penguin')));
        $data['content3'] = Lang::get('test_group.hello', array('name' => Lang::get('penguin')));

        return View::forge('test/template', $data, 'UTF-8');
    }
}
Et le modèle (fuel/app/views/test/template.php) :
<!DOCTYPE html>
<html>
<head>
    
    <?= $title ?>
</head>
<body>
    
<?= $content1 ?> <?= $content2 ?> <?= $content3 ?>
</body> </html>
Le résultat en français est :
Salut !
Salut, Pingouin !
Salut à toi, Pingouin.
Tandis qu'en anglais (en commentant la ligne Config::set('language', 'fr');), on obtient :
Hello!
Hello, Penguin!
Hello to you, Penguin.
Pour charger un fichier de langue, la classe Lang propose la méthode load. Dans cet exemple, nous chargeons les données de langue en entier, mais nous aurions tout aussi bien pu charger uniquement le groupe test en utilisant :
Lang::load('test', 'test_group');
Comme vous pouvez le voir, il est aussi possible d'utiliser un espace réservé nommé dans la chaîne traduite, préfixée par deux points (ici, :name).
En passant, la classe Lang de FuelPHP contient des méthodes pour définir une ligne spécifique dans le fichier de langue (set), pour supprimer une ligne spécifique du fichier de langue chargé (delete), et pour enregistrer un fichier de langue (save), vous permettant ainsi de mettre à jour de façon dynamique un fichier de langue.


Internationalization with FuelPHP (en anglais)
Internacionalización con FuelPHP (en espagnol)
Internacionalização com FuelPHP (en portugais)

2 commentaires:

  1. Merci pour cette présentation avec exemple très parlant.
    Vraiment sympa et facile à mettre en oeuvre cette librairie.
    Je pense la tester très prochainement dans un futur projet multilingues.

    RépondreSupprimer
  2. Bonjour,
    Oui merci effectivement.
    La doc de fuelPHP est asse simple et clair sur ce sujet mais un rappelle clair et en français sera certainement apprécié ;-).
    Cela ne concerne en revanche que les termes connus a l'avance et donc traduisible dans un fichier à l'avance (les menus, les titres, ..) mais pour tout ce qui est dynamique (des fiches produits, des profiles d'utilisateurs, ..) cette méthode ne s'applique plus et un peit article sur la gestion multilingue dans fuelphp depuis des bases de données serait également très apprécié (par moi en premier lieu ;-).
    Encore merci.

    RépondreSupprimer