Votre exigence:
Pour mon site au travail en plusieurs langues en
tant qu'utilisateur authentifié
je dois être capable de traduire à la fois tout et tous les appels de traduction dans le code de base de mon site qui ont été fait avec la fonction t ().
Cette description des exigences est-elle même proche de ce que vous demandez?
Rampeurs
Comme quelqu'un l'a dit - un robot pourrait théoriquement parcourir l'intégralité du site pour forcer l'enregistrement de tous les appels t (). Mais 1) le robot ne sait pas quelles pages explorer; 2) nous ne cherchons donc pas à maintenir une liste de pages à explorer; 3) nous ne voulons pas utiliser de robot, point final. Eww. Juste, eww. Droite?
Le problème
- Nous n'avons pas de liste de toutes les chaînes de traduction.
- Drupal / PHP est un langage dynamique contrairement à C qui est compilé. Nous ne pouvons donc pas dire par exemple: compilez toute la base de code, puis trouvez-moi toutes les instances de cette fonction
t()
, puis enregistrez ces instances dans la base de données, puis traduisez toutes ces instances enregistrées t()
en une seule fois. Je ne pense pas que ce soit une option que nous ayons sur notre table.
- Un outil d'analyse de code statique serait impuissant pour la même raison qu'un robot serait impuissant. J'ai trouvé cela
t()
dans ce fichier. Génial! Dans quelle URL est-il utilisé? Quel est le contexte?
Attaquer le problème avec les outils actuels (Drupal, et certains modules contrib), et avec les contraintes actuelles (en s'appuyant sur des appels à thème en temps réel -> fichiers modèles -> t()
appels), ressemble à une ruelle sans issue ici. Nous devrons peut-être réfléchir un peu hors de la boîte.
Ce dont nous avons besoin
- Nous avons besoin d'une source de données, d'un modèle, qui me dit quelles chaînes de traduction actuelles nous avons et quel est leur contexte -
- Modèle de données proactif. Le modèle de données actuel est réactif (le modèle est mis à jour à chaque appel
t()
). Nous avons besoin d'un modèle de données proactif - dans lequel l'application se charge de rechercher des t()
instances avant qu'elles ne soient réellement exécutées par le client.
- Nous avons besoin de contexte.
t()
seul ne suffit pas - parce que - nous ne savons pas que nous traduisons «foo», mais la langue cible vers laquelle nous traduisons dépend de l'URL de l'endroit où t()
se produit. Même si nous pouvions coder en dur la langue cible dans l' t()
appel, par exemple, en utilisant un appel wrapper, cela ne fonctionnerait pas pour vous.
J'ai identifié certains des outils qui - si nous les avions - aideraient notre problème. Avec ces outils, nous pourrions entrer dans le modèle de données et dire: donnez-moi toutes les chaînes enveloppées t()
qui n'ont pas encore été remplies. Insérez maintenant ces traductions. Je vous remercie.
Et la prochaine fois que le client vient, les traductions sont là.
Comment pourrions-nous ... construire ces outils?
Contraintes
- La langue cible ne peut pas être sur le modèle, ce qui est décidé par l'URL. En supposant que la chaîne doit prendre en charge n'importe quelle langue.
- La chaîne traduite ne peut pas se trouver sur le modèle. La traduction résidera dans une base de données.
Maintenant que j'ai réfléchi au problème et identifié certains défis et contraintes, je peux penser à examiner toutes les solutions disponibles sur le marché ou à créer des solutions personnalisées.
Remue-méninges sur la solution
J'ai besoin de quelque chose qui relie "tout" ensemble. Et ... une entité?
- Une entité peut contenir le produit à traduire.
- Les entités peuvent fournir la relation - la colle - entre le produit qui doit être traduit et son contexte.
- L'entité peut spécifier par exemple, dans un champ, l'emplacement URL par défaut du produit.
- Les jetons peuvent être utilisés pour spécifier d'autres emplacements (langues?) Sur lesquels le produit apparaîtra.
- Les entités nous fournissent le modèle de données proactif dont nous avons besoin et son contexte. Ce qui à son tour nous permet de faire des choses telles que: aller dans la base de données, récupérer toutes les entités du produit, et si elles n'ont pas de chaîne de traduction pour les champs X, Y et Z, créer ces chaînes de traduction.
Lorsque le client saisit /pl/product/200
, vous vous rendez dans la base de données, recherchez le produit 200 et récupérez la pl
traduction déjà existante . Vous avez également un champ de titre et de légende pour ce produit? Les traductions devraient être là aussi.
Notez que je suis très vague et générique ici en termes de module de traduction que vous utilisez. Vous pourriez très bien finir par utiliser votre propre module de traduction - c'est probablement le cas. Tous les modèles de traduction que j'ai vus dans Drupal jusqu'à présent (depuis D7, n'ont pas encore regardé D8) sont réactifs, pas proactifs.
En un mot
En théorie, les outils pour construire ce dont vous avez besoin sont là, les entités étant le composant clé qui relierait tout: - les données (chaîne de traduction), - les langues cibles. Pas besoin d'être sur l'entité elle-même, de préférence un vocabulaire de taxonomie, par exemple pour les langages de produit. ou peut-être aussi une taxonomie générique pour d'autres entités. - Le contexte. URL sur laquelle l'entité apparaît. L'URL contiendrait un jeton, et le jeton à son tour ferait référence à la taxonomie de la langue cible.
Avec ces trois ingrédients, vous pouvez dire: saisir toutes les product
entités, aller sur le URL alias
terrain, obtenir le jeton de taxonomie, parcourir toutes les combinaisons de termes possibles, présenter toutes les combinaisons à l'utilisateur actuel en utilisant soit une très grande forme laide - ou, AJAX - et formulaires en plusieurs étapes (quelque chose comme ça), et comme l'utilisateur actuellement connecté traduit les différentes langues du produit 200, enregistrez-les quelque part dans la base de données
Quelque part dans la base de données pourrait être un champ API de champ dans l'entité, le champ de paramètres appartenant à chaque entité (pas exactement l'API de champ, mais il peut toujours contenir des données), ou une table distincte que vous utilisez pour cela. Je pense que l'enregistrement des données dans l'entité garderait le code et les données plus propres et plus faciles.
Building It: Solutions possibles
- D8MI (Drupal 8 Multilingual Initiative)
- Code personnalisé: traductions "index" rendues disponibles dans les modèles par t () en interrogeant par programme et en rendant les bundles disponibles et leurs implémentations de hook de thème associées.
Pseudocode
Foreach entity (de type x),
Find all languages (taxonomy or core language associated with product),
Render the entity,
- afin de détecter sa chaîne de traduction t ()
- render calls theme (), qui gère la couche de présentation multilingue de le produit, pas le modèle de données produit lui-même.
Résultat:
- Le premier appel pour rendre le modèle d'entité dans chaque langue renvoie l'implémentation de langue par défaut pour chaque appel.
- Les paramètres t () du modèle sont désormais mis en cache dans Drupal et prêts à être traduits (pour chaque instance de langue, pas chaque instance de produit).
- L'utilisateur avec le rôle de «traducteur» peut maintenant accéder à l'interface de traduction et traduire tous les paramètres t () disponibles, pour chaque langue.
- Le propriétaire du site n'a pas besoin d'attendre que les clients visitent chaque page de produit ou de visiter chaque page de produit manuellement, car cela a été fait par programme pour lui.
Questions ouvertes:
- Quel est le contexte? Si j'effectue un appel programmatique au thème () pour chaque ensemble d'entités «produit», enregistre-t-il l'emplacement à partir duquel l'appel a été effectué? Enregistre-t-il l'URL du nœud? Le «contexte» peut-il être modifié? Où le contexte est-il enregistré? Que se passe-t-il lorsque vous avez des modèles «dynamiques» - c'est-à-dire lorsque vous avez plusieurs modèles par produit et comment procédez-vous pour détecter ces variations?
Comme toujours, la théorisation et le pseudocode ne sont bons que pour le brainstorming. Mais en développement, nous ne saurons pas à quoi nous nous heurterons vraiment avant de commencer le prototypage. Donc, après avoir élaboré quelques contraintes, des solutions possibles et des problèmes ou questions possibles - je peux maintenant procéder à la mise en œuvre d'une preuve de concept ou d'un prototype fonctionnel. Certaines des questions ouvertes ci-dessus ne peuvent être résolues que de cette façon, et le plus tôt nous prototypons (indépendamment du succès ou de l'échec), nous pouvons commencer à répondre à certaines de ces questions - ou changer complètement l'approche. Restez à l'écoute ~
wget
ou autre. Hackish, mais vous avez dit que c'était autorisé (: