Skip to content

Conversation

@FYHenry
Copy link
Member

@FYHenry FYHenry commented Jun 7, 2024

Internationalisation des textes

Un début d’internationalisation existe via la classe MessagesEn 1.
Ce pendant ça ne s’adapte pas encore à la langue de l’utilisateur.

Changements mineurs

Plusieurs changements mineurs sont proposés à commencer par la casse des noms de package.
D’après Oracle 2 mieux vaut passer du lower camel case au lower snake case.
myPackage.mySubpackage devient alors my_package.my_subpackage.

Ensuite vient une mise à jour des métadonnées suite aux propriétés liés aux jetons.
On sait mieux çà quoi elles correspondent.

setting.json ne sert à rien dans l’espace de travail, d’où sa suppression.

Système de traduction

Pour traduire automatiquement les réponses de l’API Rest, deux solutions m’intéressent :

  • Traduire selon l’en-tête Accept-Language 3 ;
  • Traduire selon un paramètre de requête lang 4.

Dans le premier cas tout se ferait automatiquement selon la langue indiquée par le navigateur Web.
Seulement le vrai client direct est le serveur Angular.
Il faut donc que ce dernier adapte l’en-tête HTTP selon sa propre option de langue.

Dans le second cas le serveur Spring Boot est attentif à un paramètre dans l’URL de requête.

Ce qui est compliqué : comment traduire si c’est retourné directement pas le contrôleur ou plus en amont, notamment les textes retournés par les exceptions.

Traduction par propriétés

Plus tôt que d’écrire en dur, les textes traduits peuvent être listés dans les fichiers messages${LANG}.properties dans le répertoire des resources.
LANG correspond alors aux codes linguistiques 5 comme _fr en Français ou _de en Allemand voir rien puisque l’Anglais est par défaut.

Pour aller plus loin

Pas envie de faire des doublons de traduction dans le serveur Angular ?
Nous pourrions centraliser dans ces mêmes fichiers messages*.properties.
Il suffirait de transmettre une version en JSON au serveur Angular.

Un argument contre est un couplage trop fort entre les serveurs d’Angular et de Spring Boot.

Footnotes

  1. Je m’attendais plus à une énumération.

  2. Nommage de package par Oracle.

  3. Un blog qui explique comment internationaliser selon l’en-tête Accept-language.

  4. Le guide de Baeldung pour traduire selon un paramètre de requête lang.

  5. Pour être exact le format est _lang_REGION selon les normes ISO 639-1 et 3166-1.

FYHenry added 8 commits June 6, 2024 21:59
Texte traduit selon ce qui sera indiqué dans l’en-tête HTTP `Accept-Language`.
Renommage des *packages* selon les recommendations d’Oracle.
Listes des textes à traduire.
@FYHenry FYHenry added the enhancement Fonctionnalité nouvelle label Jun 7, 2024
@FYHenry FYHenry self-assigned this Jun 7, 2024
Tentative pour avoir une réponse HTTP « localisée ».
Traduction réussie en Français mais pas en Anglais. :-/
Copy link
Member Author

@FYHenry FYHenry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ma tentative a réussi en partie.

messages_fr.properties est lu mais pas messages.properties.
Pourtant j’ai la bonne Locale en Anglais quand je débogue avec Accept-Language: en dans la requête HTTP.

.allowedOrigins(FRONTEND_HOST)
.allowedMethods("GET")
.allowedHeaders("Content-Type", "Authorization")
.exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ne faut-il justement pas mettre ici le header "Accept-Language", puisque tu veux que soit envoyé l'information sur la langue utilisée par le front ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

il faudra que tu m'en dise plus à ce sujet

@atsuhikoMochizuki atsuhikoMochizuki self-requested a review June 8, 2024 00:11
@atsuhikoMochizuki atsuhikoMochizuki marked this pull request as ready for review June 8, 2024 00:12
Copy link
Contributor

@atsuhikoMochizuki atsuhikoMochizuki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Un début d’internationalisation existe via la classe MessagesEn

=> OK je met une tâche dans le kanban pour passer MessageEn en enum

D’après Oracle 2 mieux vaut passer du lower camel case au lower snake case

=> OK

Traduire selon l’en-tête Accept-Language:

Je prèfère cette solution, ca permet de rajouter que cette informations aux quelques requêtes envoyées depuis le front, plutôt que de toucher les contrôleurs du backend.
Mais est-il vraiment pertinent de traduire le backend ?
il renvoit principalement:

  • Les données des utilisateurs : elles sont dans des variables et ils les ont rempli eux-même, avec leur propre langue.
  • Des messages d'erreurs : le backend renvoit une erreur technique, le front l'interprête (et ne l'affiche pas si c'est pas utile à un utilisateur qui n'est pas développeur).
  • Est-il utile d'envoyer à Germaine Dupoulet le message "Le JWT a expiré". La logique ne serait-elle pas que le front interprête une erreur et la rende compréhensible : Votre session a expiré: veuillez vous reconnecter.
    Pour l'instant c'est vrai que des erreurs techniques apparaissent dans les toats. Il faut que nous fassions un choix: traduire le backend, ou interprêter les messages venant du backend qui ont besoin d'être affichés.

Comment plaiderais-tu la cause favorable à la traduction de tout le backend?

Ce qui est compliqué : comment traduire si c’est retourné directement pas le contrôleur ou plus en amont, notamment les textes retournés par les exceptions.

Pour ma part dans le front:

  • la variable currentLanguage dans language-manager.service.ts permet d'adapter la langue dans toute l'application.
  • Tous les textes à afficher à l'utilisateur sont référencé dans l'objet Msg du fichier messages.constants.ts:
export const Msg = {
    webpage_staticText:{
        landing_page:{
            SLOGAN:"Take note...Wherever you are",
            SHORT_DESCRIPTION:"Inote offers a remote solution that lets you retrieve your notes at any time retrieve your notes at any time by simply logging in.",
            QUICK_REGISTRATION:"Quick registration"
        },
        publicNavBar:{
            SIGN_IN: "Sign in"
        },
        protectedNavBar:{
            PROFILE_MANAGEMENT:"Profile management",
            SIGNOUT:"Sign out",
            MY_BOARDS:"My Boards",
            MY_TEAMS:"My Teams",
            SEARCH:"Search"
        },

Ce fichier contient donc les paires clé-valeurs pour la langue anglaise par défaut. Mais également les clés, qui permettrons de récupérer la traduction, ici française, dans un map:

export const fr: Map<string, string> = new Map([
  [Msg.toasts.errors.titles.DETECTED_ANOMALY, "Anomalie détectée"],
  [
    Msg.user.errors.RECOVERY_CURRENT_USER_FAILED,
    "La récupération de l'utilisateur courant a échoué",
  ],
  
  • Pour n'importe quel texte qui doit être affiché à l'utilisateur, le programme lit la variable currentLanguage et va chercher en fonction:
pickMsg(key: string): string {
    let value: string | undefined;

    switch (this.currentLanguage) {
      case Lang.FR:
        value = fr.get(key);
        break;

      default:
        value = key;
        break;
    }

Par exemple dans le template de la landing page:

<h1 class=" mb-2 mt-2 ">{{this.lang.pickMsg(this.sloganPath)}}</h1>
<h2 class="text-body-tertiary">{{this.lang.pickMsg(this.shortDescriptionPath)}}</h2>

Ce mécanisme pourrait peut-être résoudre ton problème pour les messages des exceptions.-

En résumé : il me semble prématuré de merger cette fonctionnalité dans la main :

  • Je voudrais savoir ton point de vue quand à la nécessité de traduire le backend

De plus, pour pouvoir merger la fonctionnalité sur la main:
-- il faudrait que cette dernière fonctionne or ce n'est qu'en partie vrai d'après ce que tu dis car message.properties n'est pas chargé.
-- Il faudrait que tu valide cette fonctionnalité par des tests : envoyer une requete avec le header FR, vérifier qu'une exception ou une donnée est retournée en français, tester en anglais et tester avec une langue qui n'est pas implémentée..
-- Et vérifier que tous les tests passent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Fonctionnalité nouvelle

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants