Comment rendre les chaînes des modèles traduisibles sur toutes les pages où elles apparaissent?

14

J'ai quelques appels t()dans des fichiers * .tpl.php. Par exemple, disons que je parle de produits et de fichier product.tpl.php.

Les chaînes dans les modèles ne sont reconnues que lors de leur première utilisation. Il y avait un fil sur Drupal.org à ce sujet et j'ai trouvé que c'était exact. Malheureusement, si je vais sur, disons, http://example.com/pl/product/200 , cette chaîne sera enregistrée dans le {locales_source}tableau avec le locationchamp défini sur /pl/product/200.

J'ai besoin que mes utilisateurs puissent traduire à l'aide de l' outil de traduction sur site du module client de localisation , afin qu'ils puissent réellement voir ce qu'ils traduisent, en le plaçant dans le contexte approprié. Avec l'emplacement source défini sur /pl/product/200, le produit avec l'ID 200 est le seul sur lequel la chaîne est traduite. Et bien pire, si je peux forcer les utilisateurs à traduire sur ce produit particulier, j'ai également besoin d'eux pour pouvoir traduire en russe, et il n'y a pas de produit avec un emplacement défini sur /ru/product/PID.

Existe-t-il un moyen de reformater la chaîne d'emplacement dans la base de données, pour rendre toutes les chaînes visibles sur tous les produits, toutes les langues dans l'outil l10n_client?

J'ai essayé de le régler sur:

  • ; sites/default/themes/mytheme/product.tpl.php,
  • sites/default/themes/mytheme/product.tpl.php,
  • sites/default/modules/mymodule/mymodule.module (module qui génère des données thématiques)

Mais cela ne faisait que les rendre invisibles pour l'outil de traduction.

Je suis sûr que ce n'est pas un bogue dans le client de localisation , il montre la chaîne où il est dit que cette chaîne s'est produite. Et il semble que c'est "juste la façon dont cela fonctionne" pour le système de traduction Drupal 7 aussi - a déjà été discuté et rapporté, et rien n'a changé. Ce n'est donc pas un rapport de bogue, je demande simplement comment travailler avec ce avec quoi nous devons travailler.


Je parle de textes qui n'ont rien à voir avec le module de données qui fonctionne. Je ne veux pas traduire de produits, juste des chaînes de modèles qui n'ont rien à voir avec le produit lui-même, comme Précédent - Suivant sur le modèle de galerie d'images de produits.

Par exemple, le module renvoie 15 miniatures, et c'est le travail d'un thème d'en afficher 5 à la fois. Et les besoins altet titleattributs des liens précédents / suivants . Traduit. Mais mon module ne le sait pas. Et ne devrait jamais en avoir besoin.

Mołot
la source
Je ne sais pas si j'ai bien compris ce que vous voulez, mais l'exploration du site dans toutes les langues serait-elle suffisante? Vous pouvez utiliser par exemple. xmlsitemap pour générer les liens dans plusieurs langues, puis utiliser wgetou autre. Hackish, mais vous avez dit que c'était autorisé (:
Andy
@Andy Localization Client permet aux utilisateurs d'ouvrir une barre au bas d'une page et de traduire directement les textes qui apparaissent sur cette page, lorsqu'ils les voient. Je peux exporter tous les textes bien, mais ce n'est pas exactement le point.
Mołot
1
Je me souviens de drupal_set_message () et dpm (), que ces messages seront mis en file d'attente pour la prochaine requête, s'ils sont appelés par exemple à partir de page.tpl.php. En effet, les modèles sont généralement traités assez tard dans une demande, une fois les messages traités. Quelque chose de similaire pourrait être le cas avec t () et le client de localisation.
donquixote
Bonne question. Joli problème.
barista amateur
Juste une suggestion ... si vous souhaitez que vos utilisateurs puissent traduire vos chaînes tpl t () à tout moment dans n'importe quelle langue, vous pouvez extraire ces chaînes avec l'extracteur de modèle de traduction ( drupal.org/project/potx ) et leur donner le original .po, qu'ils pourraient traduire avec un outil tel que Poedit? ( poedit.net ). Comme vous présentez ces chaînes comme quelques chaînes statiques, le travail serait fait en même temps par chaque traducteur ...
Kojo

Réponses:

5

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

  1. Nous n'avons pas de liste de toutes les chaînes de traduction.
  2. 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.
  3. 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

  1. 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 -
  2. 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.
  3. 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

  1. 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.
  2. 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 pltraduction 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 productentités, aller sur le URL aliasterrain, 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 ~

barista amateur
la source
1
Même sans lire l'intégralité du message, ce genre de réponse mérite un vote positif
Oleg Videnov
Le point est - un outil qui prétend faire exactement ce dont j'ai besoin pour Drupal 7 existe déjà. C'est juste un problème avec Drupal qui enregistre ces chaînes avec de mauvaises métadonnées. Mais je peux changer lesdites métadonnées en db une fois les chaînes collectées, pas de problème. J'ai juste besoin de savoir à quoi les régler, pour que l'outil puisse le voir. Ou du moins, je pensais que c'était ce dont j'avais besoin. Et le plus important: je ne veux pas traduire de produits, juste des chaînes de modèles qui n'ont rien à voir avec le produit lui-même, comme Précédent - Suivant sur le modèle de galerie d'images de produits.
Mołot
2

Ok, j'ai passé plus de temps avec le module de traduction de client et d'entité de localisation pour reproduire le même scénario. Étant donné que cette réponse est totalement différente de la précédente, en ajoutant un commentaire séparé:

  1. La traduction ajoutée pour une langue dans un / premier nœud est disponible pour tous les nœuds.

    Voici un exemple:

    • Si j'ajoute un nouveau produit du même type que le nid 200 et que je visite la traduction pl du nouveau nœud (disons pl / product / 204), je verrais la même chaîne de traduction dans pl / product / 200.

    • La seule différence est qu'il n'apparaît pas dans le client de localisation. Nous pouvons demander cette fonctionnalité dans la file d'attente des problèmes du module, mais cela introduirait plus de confusion car la traduction n'est pas spécifique à la page actuelle et affecterait toutes les pages (c'est-à-dire les deux pl / product / 200 & pl / product / 204).

    • Si les deux nœuds créés par deux personnes différentes, et le dernier veut changer la traduction, alors ils doivent utiliser la traduction de l'interface.

  2. La chaîne est disponible dans le client de localisation pour la première langue que vous visitez pour le même nœud

    Voici un exemple:

    • Si j'ajoute un nouveau produit nid 199 et crée une traduction pour la langue 'pl' (nid 200) et une traduction pour la langue 'rs' (nid 201), vous pouvez voir la chaîne uniquement sur la page 'pl', pas sur la page 'rs'. Encore une fois, cela ressemble à une restriction dans le module client de localisation.
vijaycs85
la source
1

Votre approche pour ajouter la chaîne de traduction au niveau du modèle ou du fichier de module peut fonctionner pour l'interface utilisateur de traduction d'interface, mais pas pour le client de localisation.

Évidemment, lorsque vous aurez la version russe du produit 200, ce sera un nouveau nœud, par exemple / ru / product / 201, où vous pourrez traduire à l'aide du client de localisation.

Juste une pensée: recherchez une chaîne qui peut être traduite pour toutes les langues dans l'interface utilisateur de traduction d'interface et demandez au client de traduire le niveau du produit lorsque cela est vraiment nécessaire. Voici un exemple:

"C'est le produit foo de la catégorie bar"

et si nous sommes sûrs que d'autres que «foo» et «bar» peuvent être communs, nous pouvons ajouter

$vars['product_title'] = t('This is product @product of category @category')

en pré-traitement.

et le fichier .tpl.php sera

<?php t($product_title, array('@product' => t('foo'),  '@category' => t('bar')); ?>
vijaycs85
la source
Il s'agit plus de titletextes pour les flèches dans le rotateur d'images. Mon module ne se soucie pas de la façon dont le thème affichera 15 images. Et le thème affiche 5 à la fois, avec les flèches "prev" et "next" qui ont besoinalt et title, et doivent être traduites. Modifier le module à chaque fois que mon frontal changera est possible, mais ne devrait certainement pas être nécessaire. Ces chaînes n'ont rien à voir avec le module lui-même. Enfin et surtout, je ne suis peut-être tout simplement pas au courant que les chaînes du thème ont changé. Ou pas disponible pour les migrer dans le module.
Mołot
À mon humble avis, ce cas doit être traité dans l'interface de traduction de l'interface utilisateur au lieu du client de localisation.
vijaycs85
Le client de localisation vise à permettre de «corriger les traductions sur votre site lorsque vous voyez les problèmes». - pourquoi cela ne devrait pas s'appliquer aux fichiers modèles? Les chaînes en tpl sont encore plus sensibles au contexte où elles apparaissent, le cas échéant.
Mołot
1

AFAIK avec l' extracteur de modèle de traduction, vous pouvez extraire la chaîne dans tous vos appels à la t()fonction.

L'extracteur de modèle de traduction fournit une interface d'extraction de modèle de traduction Gettext basée sur le Web et en ligne de commande pour Drupal ainsi qu'une API réutilisable pour rechercher des chaînes traduisibles et des erreurs de traductibilité. Cet outil est également utilisé sous le capot à http://localize.drupal.org/ pour servir de machine d'analyse pour les versions du projet Drupal.org.

Lisez ceci Comment traduire un module?

Adrian Cid Almaguer
la source