|
Publicité ' | |||||||||||||||||||||||
|
|
#1 | ||||||||||||||||||||||||||||
![]() ![]() |
Bonjour à tous,
Cherchant une solution simple d'internationalisation de textes, j'ai fait le tour du web sans vraiment être emballé. Il faut dire aussi que j'étais exigeant : - pas de fichiers texte à rallonge - système évolutif et très modulaire - traductions statiques et paramétrables - pas de parseur autre que celui du PHP - support de l'UTF-8 - intégration dans une IDE afin de profiter de l'autocomplétion Bref un truc qui ressemble au nirvana ! Finalement, étant partisan du yaka se servir soi-même (vu que l'on est jamais mieux servi que par soi-même...) je me suis attelé à la tâche et j'ai créé un système qui répond à tous les besoins cités ci-dessus. Allez c'est parti :-) MINIMUM REQUIS La souplesse du système de traduction repose sur les dernières fonctionnalités du PHP 5.3+ : Late Static Binding et __callStatic. Donc si vous ne développez pas au minimum sous la version 5.3 de PHP, ce qui suit ne fonctionnera pas. IMPORTANT Afin d'illustrer la logique, les explications seront accompagnées d'un exemple réel provenant de mon framework d'entreprise. J'ai choisi le module fournissant les messages d'erreurs au moteur d'exécution des requêtes de la base de données. La classe d'exemple s'appelle : i18nData (dans le fichier i18nData.php) PRINCIPE Le concept : avoir des classes qui se chargent de la traduction à partir d'une classe pilote qui dérive de la classe abstraite i18n (classe en charge du mécanisme de traduction à la volée). Le développeur ne manipule que la classe pilote. Voici comment s'organisent les classes (et accessoirement les fichiers) : Code :
- GCT_LANG__USER : langue du client (lecture du header du browser) ou langue explicitement demandée par le client REGLES DE CODAGE - Les messages simple utilisent des constantes de classe FONCTIONNEMENT - Tout d'abord, il faut que le traitement normal d'une requête définisse les constantes globales : INTERCEPTION DES ERREURS : - Si pour n'importe quelle raison (fichier de traduction manquant, fonction ou constante manquante...), la traduction repart sur le langage par défaut (GCT_LANG__DEFAULT) CODE SOURCE DE LA CLASSE i18n Code :
EXEMPLE SIMPLE Classe pilote : i18nData Code :
Code :
Code :
Code :
EXEMPLE AVANCE MONTRANT UNE ARBORESCENCE DE CLASSES PILOTES On suppose qu'on a défini une classe de base à tous les formulaires regroupant quelques contrôles très communs et que l'on doive maintenant développer un formulaire plus complexe bâti sur les fondations du formulaire de base. Voici comment internationaliser tout ça : Code :
Code :
Dans tous les cas, si vous avez des questions pour l'implémentation, n'hésitez pas. Et si malgré tout mon attention, une banane s'était glissée dans le code, je suis preneur de toute remarque et commentaire qui va bien. Merci et j'espère que cela vous servira un jour.
__________________
# Dans la Création, tout est permis mais tout n'est pas utile... |
||||||||||||||||||||||||||||
|
00
|
|
|
#2 |
![]() ![]() Développeur PHP, .Net, T-SQL Inscription : décembre 2006 Messages : 2 354 ![]() |
Salut,
Joli boulot ! J'ai juste une question que reproches tu aux modèles basés sur des fichiers xml/json/yaml ? Je trouve quand même assez gênant de pouvoir ajouter les textes à traduire dans des classes php...
__________________
Développeur | Zend Certified Engineer Étapes Pour mieux se servir du forum: 1. Commencez par lire les cours et tutoriels ; 2. Faites une recherche; 3. Faites un post si rien trouvé dans les deux étapes précédentes en respectant les règles; Nix>_Rien n'est plus pratique que la théorie |
|
|
00
|
|
|
#3 |
|
Membre Expert
![]() Inscription : janvier 2007 Messages : 1 452 ![]() |
bah c'est bien tout de ce code, mais en refusant d'utiliser les librairies standards tu te coupes de bien des outils pratiquent qu'elles proposent pour gérer la pluralisation par exemple.
cf http://www.developpez.net/forums/d11...n/#post6184152 Après, je suis fondamentalement en désaccord avec ton principe de base de tout mettre dans des classes pour avoir l’auto complétion. Car avec ta solution je dois me taper tous les fichiers clients à intégrer dans des classes et les maintenir. Alors qu'avec du xml ou du yaml, tu leurs donnes un template bien fournit, ils le remplissent, tu le remplaces sur le serveur et basta. a+ |
|
|
00
|
|
|
#4 |
![]() ![]() Olivier Développeur Web Inscription : août 2003 Messages : 2 499 ![]() |
Pas convaincu non plus par le principe.
Si je ne m'abuse , si tu déclares 50 constantes de traduction dans ta classe c'est autant d'espace mémoire utilisé , alors que les données ne seront potentiellement pas utilisées. Placer tes traductions dans des fichiers php pour l'auto complétion c'est un choix , mais tu risques de vite le regretter le jour ou la traduction sera faite par des non informaticiens ou un organisme de traduction. Soit tu te fais une mécanique pour extraire les chaînes à traduire , soit tu récupères des fichiers bourrés d'erreurs 9 fois sur 10. Perso j'avais eu un peu de mal à me mettre à gettext , mais depuis je pourrais pas faire sans. |
|
00
|
|
|
#5 |
![]() ![]() |
Bonjour,
Je voulais un système de traduction léger et facile à prendre en main : plus léger c'est difficilement faisable : une classe mère et zou c'est parti. Les langues humaines étant ce qu'elles sont, les systèmes de traduction sont tous basés sur une approche clé-valeur, mon approche ne diffère pas sur ce point. Ensuite, j'aurais tendance à vous dire que j'affiche toujours des messages laconiques (dans 99% des cas, c'est une simple alerte) du genre 'date invalide', 'numérique attendu'... Je ne mets jamais un truc du genre : - Cher utilisateur, le nom que vous avez tapé est incorrectEn restant laconqiue, les besoin de pluralisation... Les messages techniques sont très très laconiques. Je ne remonte aucune information sensible du genre : - Après cinq malheureuse(s) tentative(s) de connexion à la base de données mysql, mes bits et moi-même sommes désolés de ne pas pouvoir traîter votre demandeLa traduction se limite qu'à des mots ou des phrases simples. Lorsque vous ne pouvez pas utiliser de librairie externe c'est un moyen facile d'y palier. Cette approche fonctionne parfaitement dans de nombreux cas sans se prendre la tête. Comme il est possible de faire un dictionnaire de traduction monolithique (tmx, yaml...), il est tout à fait possible de faire pareil avec mon approche. Une classe unique pour tout, bien que cela ne soit pas souhaitable. D'où la raison de la possibilité de dériver les classes de traductions les unes des autres. Si vous ne voulez pas consommer trop de ressources avec des constantes, il suffit de les remplacer par des fonctions statiques qui elles ne sont chargées que lorsqu'elles sont appelées. Et si cela devient trop fastidieux, il ne reste plus qu'à identifier les messages par des codes... Ensuite pour les très gros besoins de traduction comme par exemple pour des articles, des notices..., les systèmes automatiques sont totalement dépassés (la faute à la grammaire et aux innombrables cas particuliers lingusitiques...), il faut faire appel à un traducteur en chair et en os et là, c'est une autre problématique. Enfin, il va de soi que je n'ai jamais eu la prétention de remplacer des systèmes bien plus complets comme ICU ou gettext. C'est un détournement original des possibilités du langage PHP, c'est tout et rien de plus. Attention, classe dangereuse : à utiliser avec précautions
__________________
# Dans la Création, tout est permis mais tout n'est pas utile... |
|
00
|
|
|
#6 | ||||
![]() ![]() Benjamin DelespierreDéveloppeur Web Inscription : février 2010 Messages : 3 891 ![]() |
Hello
Je trouve ta solution un peux complexe pour ce qu'elle propose: elle suppose la création de classes supplémentaires pour ajouter des langues, ce qui n'est pas bien pratique. En plus elle demande nécessairement PHP 5.3 et tous les hébergeurs ne le proposent pas encore. D'ailleurs, quitte à utiliser PHP 5.3 pourquoi ne pas se servir des namespaces ? Je posterai plus tard dans un thread séparé, mais si ça t'inspire voici ma classe de gestion i18n: Code :
Usage (à titre d'exemple seulement): Code :
- Reconnaissance automatique de la langue - Chargement automatique des traductions depuis des fichiers ini - Gestion des dates, prise en compte des formats humains (par exemple "Il y a 3 jours") - Gestion de n locales disponibles - Offre des typo helpers pour faciliter son utilisation - Remplacement de placeholders (syntaxe printf) dans les traductions Prérequis: - PHP 5.1 Aucune définition de variables / constante externe n'est requise, tout passe par Lang::setConfig. Je n'ai pas cherché à aller plus loin car cette classe est déjà assez performante et couvre 99% de mes besoins. De toute façon si on veut allez jusqu'au bout du problème de l’internationalisation, il faut utiliser gettext, y'a pas 36 solutions.
__________________
On vous a menti PHP, Injection de dépendances et composants La POO en PHP en 10 minutes pour moins Suivez-moi sur GitHub et TwitterN'oubliez pas de vous servir des bouttons , et
|
||||
|
00
|
|
|
#7 |
![]() ![]() Inscription : septembre 2010 Messages : 7 958 ![]() |
je préfère de loin ICU que gettext, MessageFormatter est simple a utilisé, après faut créer les ressource a partir de XLIFF ou/et RB Manager, la classe est bouclé en quelque ligne
__________________
http://blog.stealth35.com/ |
|
|
00
|
|
|
#8 | ||
![]() ![]() |
Voici le code source de la classe postée précédemment avec un raccourcissement du code et amélioration des perfs :
Code :
__________________
# Dans la Création, tout est permis mais tout n'est pas utile... |
||
|
00
|
|
|
#9 | ||
![]() ![]() Inscription : septembre 2010 Messages : 7 958 ![]() |
qu'est ce que c'est que ça
Code :
__________________
http://blog.stealth35.com/ |
||
|
|
10
|
|
|
#10 | ||
![]() ![]() |
Bah écoutes une horreur monstrueuse
Faut avouer que je n'y ai pas pensé, ![]() Allez voici la version sacrément raccourcie dis donc : Code :
__________________
# Dans la Création, tout est permis mais tout n'est pas utile... |
||
|
00
|
Copyright © 2000-2013 - www.developpez.com