Volver

gt-next@6.8.0

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

Resumen

A menudo vemos que, cuanto más madura es una base de código, más fragmentado está el contenido. Las frases quedan dispersas entre funciones, utilidades, lógica y servicios.

function getSubject(gender) { 
  return gender === "male" ? "boy" : "girl" 
}
function getObject(toy, gender) { 
  return toy === "ball" ? "ball" : getSubject(gender)
}

function Component({ gender, toy }) {
  return (
    <>
      <p>
        The beautiful {getSubject(gender)} plays with the {getObject(toy, gender)}.
      </p>
    </>
  )
}

Cuando inevitablemente llega el momento de internacionalizar, los desarrolladores descubren que se han metido en un callejón sin salida. Aplicar aspectos como la concordancia, la conjugación y los cambios en el orden de las palabras en varios archivos no es viable sin una refactorización importante. Tradicionalmente, esto implicaba extraer manualmente todas las permutaciones posibles de cada oración y añadirlas a un diccionario de traducción.

En gt-next 6.8.0, reforzamos nuestra convicción de que una buena biblioteca de i18n debe adaptarse a una base de código, y no al revés. Aunque gt-next ya traduce contenido en línea, le siguen faltando dos características fundamentales de una biblioteca de este tipo: (1) soporte para la fragmentación de oraciones y (2) contenido reutilizable, manteniendo al mismo tiempo la concordancia, la conjugación y los cambios en el orden de las palabras.

Presentamos el componente <Static> para permitir llamadas a funciones estáticas directamente dentro de las traducciones.

function getSubject(gender) { 
  return gender === "male" ? "boy" : "girl" 
}
function getObject(type, gender) { 
  return type === "ball" ? "ball" : getSubject(gender)
}

function Component({ gender, toy }) {
  return (
    <T>
      <p>
        The beautiful <Static>{getSubject(gender)}</Static> plays with the <Static>{getObject(toy, gender)}</Static>.
      </p>
    </T>
  )
}

Consideraciones importantes

Dicho esto, insistimos en usar el componente <Static> con cuidado y criterio. Aunque el componente <Static> es muy potente, también puede aumentar considerablemente la cantidad de entradas de traducción. Si se usa de forma incorrecta, esto podría afectar negativamente los tiempos de carga de la aplicación.

Cómo usar <Static>

Al igual que los componentes <T> y <Var>, el componente <Static> es una marca que le indica a la herramienta CLI dónde debe buscar contenido traducible y dónde no. Le indica a la herramienta CLI que resuelva una llamada de función dentro de las etiquetas <Static> y catalogue todo el contenido posible que esa función puede devolver. Trata cada instrucción return como si estuviera envuelta en un componente <T>.

Una vez que la herramienta CLI ha encontrado todos los resultados posibles de una llamada de función, crea una entrada de traducción independiente para cada uno. Por ejemplo, el siguiente código crea dos entradas de traducción independientes: "The boy is beautiful" y "The girl is beautiful". Como existe una entrada de traducción distinta para cada resultado posible, podemos admitir concordancia, conjugación y orden de palabras en una oración fragmentada: "El niño es hermoso" y "La niña es hermosa".

function getSubject(gender) { 
  return gender === "male" ? "boy" : "girl" 
}
function Component({ gender }) {
  return (
    <T>
      The <Static>{getSubject(gender)}</Static> is beautiful.
    </T>
  )
}

Limitaciones y futuras mejoras

Multiplicación

Como se mencionó antes, el componente <Static>, si se usa en exceso, puede generar una gran cantidad de entradas de traducción, lo que podría afectar negativamente el rendimiento de carga. Por ejemplo, considera un componente con dos componentes <Static>, cada uno envolviendo una llamada a función con dos resultados posibles. En este caso, se crean cuatro entradas de traducción. Cada componente <Static> adicional multiplica el número de traducciones por la cantidad de resultados posibles de cada llamada a función.

function getSubject(gender) { 
  return gender === "male" ? "boy" : "girl" 
}
function getObject(toy) { 
  return toy === "ball" ? "ball" : "crayon"
}
function Component({ gender, toy }) {
  return (
    <T>
      <Static>{getSubject(gender)}</Static> plays with the <Static>{getObject(toy)}</Static>.
    </T>
  )
}

Sintaxis

Es importante tratar cada sentencia return como si estuviera envuelta en un componente <T>. Las variables o llamadas a funciones que sean dinámicas deben seguir envueltas en componentes <Var>.

Actualmente, <Static> solo admite llamadas a funciones como children, pero en el futuro podrá admitir expresiones más complejas. A partir de gt-next 6.8.0, se admite la siguiente sintaxis para las funciones estáticas:

function getExamples(key) {
  switch (key) {
    case "string, number, and boolean literals":
      if (condition1) {
        return "The boy"
      } else if (condition2) {
        return 22
      } else {
        return true
      }
    case "jsx expressions":
      return (
        <>
          Hello, <Static>{getTitle(title)}</Static>. How are you, <Var>{name}</Var>?
        </>
      );
    case "ternary operators":
      return condition ? "The boy" : "The girl"      
    case "function calls":
      return otherStaticFunction();
  }
}

Conclusión

gt-next 6.8.0 incorpora el componente <Static> como solución a la fragmentación de oraciones sin sacrificar la cobertura de traducción ni la concordancia gramatical adecuada.