Retour

gt-next@6.8.0

Ernest McCarter avatarErnest McCarter
gt-reactgt-nextgtx-cliv6.8.0statictranslationi18n

Vue d’ensemble

On constate souvent que plus une base de code est mature, plus le contenu est fragmenté. Les phrases se retrouvent éparpillées entre les fonctions, les utilitaires, la logique et les services.

function getSubject(gender) { 
  return gender === "male" ? "garçon" : "fille" 
}
function getObject(toy, gender) { 
  return toy === "ballon" ? "ballon" : getSubject(gender)
}

function Component({ gender, toy }) {
  return (
    <>
      <p>
        {getSubject(gender) === "garçon" ? "Le beau" : "La belle"} {getSubject(gender)} joue avec {getObject(toy, gender) === "ballon" ? "le" : getSubject(gender) === "garçon" ? "le" : "la"} {getObject(toy, gender)}.
      </p>
    </>
  )
}

Quand vient inévitablement le moment d'internationaliser, les développeurs se rendent compte qu'ils se sont enfermés dans un coin. Imposer des règles comme l'accord, la conjugaison et les changements d'ordre des mots à travers plusieurs fichiers n'est pas gérable sans un important refactoring. Traditionnellement, cela signifiait extraire manuellement toutes les permutations possibles de chaque phrase et les ajouter à un dictionnaire de traduction.

Dans gt-next 6.8.0, nous redoublons d'efforts sur l'idée qu'une bibliothèque i18n robuste s'adapte à une base de code, et non l'inverse. Bien que gt-next traduise déjà le contenu en ligne, il lui manque deux fonctionnalités fondamentales pour ce type de bibliothèque : (1) la prise en charge de la fragmentation des phrases et (2) la possibilité de réutiliser du contenu tout en préservant l'accord, la conjugaison ou les changements d'ordre des mots.

Nous introduisons le composant <Static> pour permettre les appels de fonctions statiques directement à l'intérieur des traductions.

function getSubject(gender) { 
  return gender === "male" ? "garçon" : "fille" 
}
function getObject(type, gender) { 
  return type === "ballon" ? "ballon" : getSubject(gender)
}

function Component({ gender, toy }) {
  return (
    <T>
      <p>
        <Var>Le beau</Var> <Static>{getSubject(gender)}</Static> joue avec <Var>le</Var> <Static>{getObject(toy, gender)}</Static>.
      </p>
    </T>
  )
}

Points importants à prendre en compte

Cela étant dit, nous recommandons vivement d’utiliser le composant <Static> avec soin et discernement. Le composant <Static>, bien que puissant, peut également entraîner une augmentation importante du nombre d’entrées de traduction. S’il est utilisé de manière inappropriée, cela pourrait avoir des effets négatifs sur les temps de chargement d’une application.

Comment utiliser <Static>

Tout comme les composants <T> et <Var>, le composant <Static> sert de repère pour indiquer à l’outil CLI où chercher — ou ne pas chercher — du contenu traduisible. Il indique à l’outil CLI de déréférencer un appel de fonction à l’intérieur des balises <Static> et de répertorier tous les contenus possibles renvoyés par cette fonction. Considérez chaque instruction return comme si elle était enveloppée dans un composant <T>.

Une fois que l’outil CLI a trouvé toutes les sorties possibles d’un appel de fonction, il crée une entrée de traduction distincte pour chacune d’elles. Par exemple, le code suivant crée deux entrées de traduction distinctes : "The boy is beautiful" et "The girl is beautiful". Comme une entrée de traduction différente existe pour chaque sortie possible, nous pouvons gérer l’accord, la conjugaison et l’ordre des mots dans une phrase fragmentée : "El niño es hermoso" et "La niña es hermosa".

function getSubject(gender) { 
  return gender === "male" ? "boy" : "girl" 
}
function Component({ gender }) {
  return (
    <T>
      Le <Static>{getSubject(gender)}</Static> est beau.
    </T>
  )
}

Limites et améliorations futures

Multiplication

Comme mentionné précédemment, le composant <Static>, s'il est utilisé de manière trop intensive, peut générer un grand nombre d'entrées de traduction, ce qui peut avoir un impact négatif sur les temps de chargement. Par exemple, imaginons un composant contenant deux composants <Static>, chacun encapsulant un appel de fonction avec deux résultats possibles. Dans ce cas, quatre entrées de traduction sont créées. Chaque composant <Static> supplémentaire multiplie le nombre de traductions par le nombre de résultats possibles de chaque appel de fonction.

function getSubject(gender) { 
  return gender === "male" ? "garçon" : "fille" 
}
function getObject(toy) { 
  return toy === "ball" ? "ballon" : "crayon"
}
function Component({ gender, toy }) {
  return (
    <T>
      <Static>{getSubject(gender)}</Static> joue avec <Static>{getObject(toy)}</Static>.
    </T>
  )
}

Syntaxe

Il est important de traiter chaque instruction return comme si elle était entourée d’un composant <T>. Toutes les variables ou tous les appels de fonction dynamiques doivent malgré tout être encapsulés dans des composants <Var>.

Actuellement, <Static> ne prend en charge que les appels de fonction comme enfants, mais à l’avenir il pourra gérer des expressions plus complexes. Depuis gt-next 6.8.0, la syntaxe suivante est prise en charge pour les fonctions statiques :

function getExamples(key) {
  switch (key) {
    case "littéraux de chaîne, nombre et booléen" :
      if (condition1) {
        return "Le garçon"
      } else if (condition2) {
        return 22
      } else {
        return true
      }
    case "expressions jsx" :
      return (
        <>
          Bonjour <Static>{getTitle(title)}</Static>. Comment allez-vous, <Var>{name}</Var> ?
        </>
      );
    case "opérateurs ternaires" :
      return condition ? "Le garçon" : "La fille"      
    case "appels de fonction" :
      return otherStaticFunction();
  }
}

Conclusion

gt-next 6.8.0 introduit le composant <Static> comme solution au morcellement des phrases, sans sacrifier la couverture des traductions ni le respect des accords grammaticaux.