Outils pour utilisateurs

Outils du site


public:nommage_symboles_externalisation

Externalisation des messages

Cette page définit notamment de la façon de créer les symboles d'externalisation des chaînes de TXM.

Externaliser les messages consiste à séparer les messages dans 3 lieux :

  • les sources Java : contient les clés (usages des messages)
  • les fichiers messages.properties : contiennent l'association clés + messages
  • un fichier Messages.java : contient des variables Java support des messages (instanciés en fonction de la locale)

Nommage des symboles d'externalisation des messages

Nommage automatique d'Eclipse

L'outil d'externalisation d'Eclipse propose directement des symboles pour les chaînes en utilisant le nom de la classe dont on externalise les chaînes et un numéro de chaîne (externalisée ou pas).

Par exemple : ProgressionPreferencePage_3

Suppression des chaînes en doubles dans TXM

Pour faciliter la tâche des traducteurs, nous avons :

  • limité le nombre de fichiers à manipuler (1 par plugin)
  • fusionné les doublons

La fusion des doublons a rendu les clés moins liées aux packages Java.

Propositions de convention de nommage des symboles/constantes des chaînes

TODO : existe-t-il déjà quelque part des recommandations à ce sujet ?

TODO : lister les différents cas de figures pour en déduire la convention de nommage ? ex :

  • classe contenant une seule commande/action
  • classe contenant plusieurs commandes/actions
  • cible de la sortie texte ? ex :
    • ChartsEnginePreferencePage_SELECT_ENGINE_COMBO_FIELD_LABEL=Current Engine
    • ChartsEnginePreferencePage_LOG_RECREATING_CHARTS_ENGINE=Recreating Charts Engine and Charts SWT component provider ?
WIP SJ pendant le split (2018-04.10)

Propositions SJ, messages.properties, notamment basées sur les sources d'Eclipse/SWT et sur d'autres recherches :

Les chaînes étant maintenant localisées dans chaque plugin, les préfixes avec nom de la classe ne semblent plus utiles. Le nom de la classe de Messages elle-même étant suffisamment parlant, ex. :

  • CACoreMessages
  • CAUIessages
  • RCoreMessages
  • etc.

0) arrêter de concaténer des chaînes directement dans Java mais toujours utiliser NLS.bind() et ajouter les arguments directement dans les .properties : {0} {1} etc. Cela évite le split de chaînes intraduisibles, le codage en dur et les annotations NON-NLS.

  • avant l'externalisation, se forcer à binder directement les paramètres dans le code source, ex. : Log.info(TXMCoreMessages.bind(“The '{0}' package is not installed. Trying to install it now…”, p));

1) “destination/type”

  • common_ (dédié notamment aux chaînes partagées et stockées dans la couche Core/TBX ou RCP mais également dans les plugins d'abstraction, ex. searchengine va partager des messages pour searchengine.cqp et searchengine.tigersearch)
  • info_
  • error_
  • warning_
  • export_ (dédié à la création de fichiers exportés, ex. export_cooccurrence_table_header ⇒ Occ\tFreq\tCoFreq\tScore\tMeanDist\tMode)
  • etc. TBD

2) “localisation/emplacement”

TBD, peut-être :

  • charts_factorialMap_
  • editor_toolbar_
  • preferences_
  • etc.

3) la fin de la clé est la phrase en anglais, sans majuscule au début et prenant ensuite une majuscule à chaque mot. Code beaucoup plus clair + plus de précisions pour les traducteurs, etc., ex :

  • errorWhileComputingCA
  • lexicalTableNotFoundInWorkspace
  • unableToExtractSingularValues
  • etc.

4) Propositions/exemples complets :

  • TXMCoreMessages.common_strucutralUnit
  • TXMCoreMessages.common_pleaseWait
  • TXMCoreMessages.common_units
  • TXMCoreMessages.common_delete
  • TXMCoreMessages.common_ok
  • TXMCoreMessages.error_error
  • CACoreMessages.common_mass
  • CACoreMessages.common_dist
  • CACoreMessages.charts_factorialMap_tooltipRowsLabel
  • RCoreMessages.error_failedToLoadLibrary
  • RCoreMessages.info_lastSafeEvalExpression
  • TXMUIMessages.common_displayOptions
  • RCoreMessages.error_failedToConnectToTheRWorkspace
  • RCoreMessages.error_failedToInitializeFileTransfert
  • RCoreMessages.error_failedToKillRServe2
  • RCoreMessages.error_failedToKillRServe3
  • RCoreMessages.error_failedToKillRServe
  • RCoreMessages.info_startingRUsingPath
  • CAUIMessages.charts_editor_toolbar_button_tooltip_showHidePointShapes (⇐ oui j'avoue, ça le fait moyen ! mais bon ça permettrait d'utiliser ensuite la vue hiérarchique du Bundle Ressource Editor)

Localisation des fichiers des chaînes externalisées

Proposition de localisation des fichiers Messages.java et .properties

SJ : Pour plus de facilité, je propose de regrouper les fichiers Messages.java et les .properties dans un package nommé 'messages'. Je propose également de renommer le fichier Messages.java en y ajoutant en préfixe un identifiant du plugin. Voici ce que ça donnerait par exemple pour le plugin org.txm.tbx.chartsengine :

  • org.txm.tbx.chartsengine.base.ChartsEngine.java
  • org.txm.tbx.chartsengine.base.messages.ChartsEngineMessages.java (le fichier originellement appelé Messages.java)
  • org.txm.tbx.chartsengine.base.messages.messages.properties
  • org.txm.tbx.chartsengine.base.messages.messages_fr.properties

Le renommage du fichier Messages.java par un nom plus explicite facilite l'accès aux messages car un même plugin peut utiliser la classe Messages.java de plusieurs autres plugins liés, ce qui prête à confusion.

La méthode de nommage dynamique du BUNDLE_NAME décrite ci-dessous fonctionne au runtime mais le problème est qu'Eclipse ne peut pas faire le lien entre la classe et les fichiers .properties donc le rollover sur une constante de Messages.java dans l'IDE n'affiche pas la chaîne de caractères.

Le BUNDLE_NAME généré par la fonction 'Externalize Strings' d'Eclipse est codé en dur en fonction du package dans lequel se trouve la classe Messages.java au moment de l'externalisation. Pour simplifier le refactoring on peut remplacer :

public class ChartsEngineMessages extends NLS {
private static final String BUNDLE_NAME = "org.txm.tbx.chartsengine.base.messages"; //$NON-NLS-1$
...
}

par :

public class ChartsEngineMessages extends NLS {
private static final String BUNDLE_NAME = ChartsEngineMessages.class.getPackage().getName() + ".messages"; //$NON-NLS-1$
...
}

Le BUNDLE_NAME est alors généré dynamiquement en fonction du package réel de la classe.

Dispatch des fichiers des chaînes

Si la Toolbox et la RCP s'orientent vers un découpage du code en plugins il faudrait réfléchir aux bénéfices et aux inconvénients liés à la décentralisation des fichiers des chaînes vers chaque plugin. Ci-dessous première réflexion :

Pros

  • le dispatch des fichiers par plugin auquel les chaînes sont liées devraient faciliter la navigation dans ces fichiers et ces chaînes depuis les différents projets dans l'IDE
  • le plugin a une vie autonome avec ses fichiers de langues associées ce qui facilite a priori les mises à jour, la suppression, le refactoring
  • la traduction des chaînes peut être mutualisée entre plusieurs personnes et ceci par plugin. (En fait c'est peut-être plutôt un cons)
  • cela facilite le développement de plugin par des tiers
  • Tiré de http://www.eclipse.org/articles/Article-Internationalization/how2I18n.html#step5 : “At this point, we could simply copy our domestic language property files to similarly named files with locale-specific suffixes (for example, MyMessages_xx.properties, where xx is the language), and move to step 6, Prepare and send domestic language materials for translation. In this case, the product is delivered with its code and whatever languages it supports as a single install. However, this approach has a few drawbacks. Firstly, the code and its national language resources are intermingled in the same directory / JAR file. If the translation lags the code delivery, the plug-in JAR file must be updated, despite the fact that the underlying code is unchanged. Secondly, files other than property files are not inherently locale-sensitive, so they must be segregated to separate directories for each language (for example, HTML, XML, images)”.

Cons

  • cela semble compliquer énormément la gestion, la maintenance et la traduction de ces fichiers
Rappel des préconisations de base

D'après le tuto et d'autres recherches, les préconisations seraient d'avoir :

  • le projet/plugin contenant les chaînes de caractères par défaut
  • un projet fragment pour chaque langue additionnelle et basé sur le plugin parent

TODO : voir la fonction Internationalize d'Eclipse qui entre autres permet de créer directement un ou plusieurs projets fragment à partir d'un plugin et d'une liste de locales spécifiée.

Après test de la fonction, elle crée donc un fragment par langue additionnelle ou un seul fragment pour toutes les langues. Elle crée également directement les bundle_xx.properties et les messages_xx.properties dans le ou les fragments en fonction de chaque locale spécifiée lors de son exécution.

Conventions à partir de TXM 0.8.0

  • les noms des fichiers *Messages.java se terminent par “Messages.java”
  • les fichiers de messages sont regroupés dans un package "org.txm.<plugin>.[core|rcp].messages"
  • la syntaxe des clés est (préfixe_)?messageNormaliseSansAccentEtSansNombreSaufPourLesParametresDeBind
    • les paramètres de binding sont nommés P0, P1, P2, etc.
    • exemple : “File {0} not found.” → fileP0NotFound
    • la partie suivant le préfixe est régénérée lorsque le message est modifié
  • on limite la création de doublons
  • on limite les messages et/ou clés non utilisés
  • on utilise le NLS.bind() plutôt que la concaténation de messages
  • une chaîne de message de log doit se terminer par un point sauf s'il s'agit du début d'un processus, dans ce cas mettre 3 points indiquant le traitement (concrètement verbe en “ing” ⇒ 3 points). Exemple :
    System.out.print(NLS.bind(Messages.WritingCoocMatrixInGraphmlFileDDotP0, file));
    working();
    System.out.println(Messages.FileCreated);
    ->
    Writing cooc matrix in GRAPHML file: {0}... File created. 

Conventions de rédaction des messages

Règles d'harmonisation terminologique dans les messages FR et EN et pour la traduction entre ces deux langues.

Conventions générales

  • pas TXM comme préfixe de messages

Conventions Lexique

FR

  • « dossier X » au lieu de « répertoire X »
  • « platforme » à la place de « toolbox », « boîte à outils » ou « noyau »
  • « fenêtre de résultats » au lieu d' « onglet de résultats » ou « éditeur »
  • « erreur » au lieu de « exception »
  • « identifiant de corpus » au lieu de « nom de corpus »

EN

  • « folder X » au lieu de « X directory »
  • « platform » à la place de « toolbox » ou « core »
  • « result window » à la place d' « editor »
  • « error » au lieu de « exception »
  • « descendent » au lieu de « descendant »
  • « corpus identifier » au lieu de « corpus name »

Conventions d'écriture (contenu)

Conventions valables pour les chaines de widget et pour les messages de console (sauf cas particuliers mentionnés).

Pour pouvoir être appliquées, ces règles ne doivent pas être utilisées en écoutant de la musique binaire.
  • une chaîne de message de log doit se terminer par un point (“.”)
  • les messsages sont rédigés avec des mots complets (pas d'abbréviation, e.g. 'temp')
  • pas de quotes ou guillemets (' ', “ ”, « ») autour des noms de fichiers et de répertoires en tant qu'arguments (e.g. {0} ), mais possible pour les noms littéraux (e.g. txm)
  • les noms de commandes et leur tooltip doivent comporter un verbe conjugué à l'infinitif (eg “Exporter les annotations CQP”)
    • sauf s'il s'agit du début d'un processus, dans ce cas mettre 3 points indiquant le traitement (“…”)
  • si le message est paramétré, doubler les guillemets simples (" '' ")
  • trois formats de niveaux de messages de console
    • normal : pas de préfixe ''
    • warning/attention : '** '
    • erreur : '** Erreur : '
  • les phrases commencent par une majuscule après '' et '** '
  • les phrases commencent par une minuscule après '** Erreur : '

Procédure de traduction et de vérification

  • les chaines et messages à traduire et vérifier ont la valeur “null” (pas de traduction)
  • il faut traduire tous les “nulls”

Questions 0.8.3beta

  • quel est le contexte de “126, rcp.messages.TXMUI.command.description.10, Revert” = Annuler ?
    • MD: pas utilisé c'était un test pour rétablir des paramètres d'un résultat avec CTRL+Z
      • SLH : “Rétablir” pour FR donc
  • quel est le contexte de “263, rcp.messages.TXMUI.command.name.115, ExportResultFromEditor, null” ?
    • MD: pas utilisé, c'était pour brancher la commande d'export dans la toolbar des éditeurs
      • SLH : on n'aura pas de bouton pour l'export dans la toolbar ? (ni d'import ?)
  • dans “381, rcp.messages.TXMUI.commandParameter.name, File, fichier” et d'autres, pourquoi le français ne commence pas par une majuscule ?
    • MD: on peut ignorer les “commandParameter.name”, c'est le nom des paramètres des commandes RCP. C'est plus de la doc developpeur qu'utilisateu
      • SLH : OK on ignore donc
  • quels sont les contextes de :
381
rcp.messages.TXMUI.commandParameter.name
File
fichier
382
rcp.messages.TXMUI.commandParameter.name.1
Script
script
etc.
  • répétitions
    • Recover corpora
    • Edit
    • MD: il peut y avoir des répétitions entre le nom de la commande et le nom de l'entrée de menu (entre autres). Meme si dans l'immédiat le nom est le même, cela peut changer + tard pour X raisons
      • SLH : OK on ignore donc
public/nommage_symboles_externalisation.txt · Dernière modification : 13/06/2023 10:13 de matthieu.decorde@ens-lyon.fr