From 401eab50627454e7994b947b5df2871fca2dd126 Mon Sep 17 00:00:00 2001 From: Rodrigo Antinarelli Date: Fri, 7 Jun 2019 19:53:30 -0300 Subject: [PATCH 1/6] update i18n documentation --- docs/latest/essentials/translating.md | 221 ++++++++++++++++---------- 1 file changed, 141 insertions(+), 80 deletions(-) diff --git a/docs/latest/essentials/translating.md b/docs/latest/essentials/translating.md index f14e2353c..459567a3a 100644 --- a/docs/latest/essentials/translating.md +++ b/docs/latest/essentials/translating.md @@ -1,154 +1,215 @@ # Translating -OHIF supports internationalization using [i18next](https://www.i18next.com/) through the npm package [ohif-i18n](https://www.npmjs.com/package/ohif-i18n), where is the main instance of i18n containing several languages and tools. + +OHIF supports internationalization using [i18next](https://www.i18next.com/) +through the npm package [@ohif/i18n](https://www.npmjs.com/package/@ohif/i18n), +where is the main instance of i18n containing several languages and tools. ### Installing + ```bash -yarn add ohif-i18n +yarn add @ohif/i18n # OR -npm install --save ohif-i18n +npm install --save @ohif/i18n ``` ### How it works -After installing `ohif-i18n` npm package, the translation function [t](https://www.i18next.com/overview/api#t) can be used [with](#with-react) or [without](#without-react) React. -A translation will occur every time a text match happens in a [t](https://www.i18next.com/overview/api#t) function. +After installing `@ohif/i18n` npm package, the translation function +[t](https://www.i18next.com/overview/api#t) can be used [with](#with-react) or +[without](#without-react) React. -The [t](https://www.i18next.com/overview/api#t) function is responsible for getting translations using all the power of i18next. +A translation will occur every time a text match happens in a +[t](https://www.i18next.com/overview/api#t) function. + +The [t](https://www.i18next.com/overview/api#t) function is responsible for +getting translations using all the power of i18next. E.g. Before: -````html -
my translated text
-```` -After: -````html -
{t('my translated text')}
-```` -If the translation.json file contains a key that matches the HTML content e.g. `my translated text`, it will be replaced automatically by the [t](https://www.i18next.com/overview/api#t) function. +```html +
my translated text
+``` + +After: + +```html +
{t('my translated text')}
+``` + +If the translation.json file contains a key that matches the HTML content e.g. +`my translated text`, it will be replaced automatically by the +[t](https://www.i18next.com/overview/api#t) function. --- + #### With React -This section will introduce you to [react-i18next](https://react.i18next.com/) basics and show how to implement the [t](https://www.i18next.com/overview/api#t) function easily. + +This section will introduce you to [react-i18next](https://react.i18next.com/) +basics and show how to implement the [t](https://www.i18next.com/overview/api#t) +function easily. ##### Using HOCs -In most cases we used [High Order Components](https://react.i18next.com/latest/withtranslation-hoc) to get the `t` tool between OHIF's components. -E.g. - -```js -import React from 'react'; -import { withTranslation } from 'ohif-i18n'; - -function MyComponent({ t, i18n }) { - return

{t('my translated text')}

-} - -export default withTranslation('MyNameSpace')(MyComponent); -``` -> Important: if you are using React outside the OHIF Viewer, check the [I18nextProvider](#using-outside-of-ohif-viewer) section, `withTranslation` HOC doesnt works without a I18nextProvider - -##### Using Hooks -Also, it's possible to get the `t` tool using [React Hooks](https://react.i18next.com/latest/usetranslation-hook), but it requires at least React > 16.8. - - -#### Using outside of OHIF viewer -OHIF Viewer already sets a main [I18nextProvider](https://react.i18next.com/latest/i18nextprovider) connected to the shared i18n instance from `ohif-i18n`, -all extensions inside the Viewer will share this same provider at the end, you don't need a provider when developing a react Extension if you use `ohif-i18n`; - -But, if you need to use it completely outside of OHIF viewer, you can set the I18nextProvider this way: - -```js -import i18n, { I18nextProvider } from 'ohif-i18n'; -import App from './App'; - - - - -``` -After setting `I18nextProvider` in your React App, all translations from `ohif-i18n` should be available following [With React](#with-react) usage. - ----- - -#### Without React -When needed, you can also use available translations *without React*. +In most cases we used +[High Order Components](https://react.i18next.com/latest/withtranslation-hoc) to +get the `t` tool between OHIF's components. E.g. ```js -import { t } from 'ohif-i18n'; -console.log( t('my translated text') ); +import React from 'react'; +import { withTranslation } from '@ohif/i18n'; + +function MyComponent({ t, i18n }) { + return

{t('my translated text')}

; +} + +export default withTranslation('MyNameSpace')(MyComponent); +``` + +> Important: if you are using React outside the OHIF Viewer, check the +> [I18nextProvider](#using-outside-of-ohif-viewer) section, `withTranslation` +> HOC doesnt works without a I18nextProvider + +##### Using Hooks + +Also, it's possible to get the `t` tool using +[React Hooks](https://react.i18next.com/latest/usetranslation-hook), but it +requires at least React > 16.8. + +#### Using outside of OHIF viewer + +OHIF Viewer already sets a main +[I18nextProvider](https://react.i18next.com/latest/i18nextprovider) connected to +the shared i18n instance from `@ohif/i18n`, all extensions inside the Viewer +will share this same provider at the end, you don't need a provider when +developing a react Extension if you use `@ohif/i18n`; + +But, if you need to use it completely outside of OHIF viewer, you can set the +I18nextProvider this way: + +```js +import i18n, { I18nextProvider } from '@ohif/i18n'; +import App from './App'; + + + +; +``` + +After setting `I18nextProvider` in your React App, all translations from +`@ohif/i18n` should be available following [With React](#with-react) usage. + +--- + +#### Without React + +When needed, you can also use available translations _without React_. + +E.g. + +```js +import { t } from '@ohif/i18n'; +console.log(t('my translated text')); ``` --- # Main Concepts While Translating -### - Namespaces -Namespaces are being used to organize translations in smaller portions, combined semantically or by use. -Each `.json` file inside `ohif-i18n` npm package becomes a new namespace automatically. +### - Namespaces +Namespaces are being used to organize translations in smaller portions, combined +semantically or by use. Each `.json` file inside `@ohif/i18n` npm package +becomes a new namespace automatically. - Buttons: All buttons translations - CineDialog: Translations for the toll tips inside the Cine Player Dialog - common: all common jargons that can be reused like `t('$t(common:image)')` - Header: translations related to OHIF's Header Top Bar -### - Extending Languages in ohif-i18n -Sometimes, even in the same language, some nouns or jargons can change in different countries, states or even from Hospital to Hospital, in this cases, we can extend languages. +### - Extending Languages in @ohif/i18n -To extend a language, create a new folder inside a language with two characters as name, like the `UK` in the following file tree: +Sometimes, even in the same language, some nouns or jargons can change in +different countries, states or even from Hospital to Hospital, in this cases, we +can extend languages. + +To extend a language, create a new folder inside a language with two characters +as name, like the `UK` in the following file tree: Files Tree for Extending Purpouses -All properties inside a Namespace (.json file) will be replaced in the new sub language, e.g en-US, en-UK, es-AR, es-MX, etc. - +All properties inside a Namespace (.json file) will be replaced in the new sub +language, e.g en-US, en-UK, es-AR, es-MX, etc. #### - Extending languages dynamically -Once you have access to the i18n instance, you can use the [addResourceBundle](https://www.i18next.com/how-to/add-or-load-translations#add-after-init) method to add and change language resources. +Once you have access to the i18n instance, you can use the +[addResourceBundle](https://www.i18next.com/how-to/add-or-load-translations#add-after-init) +method to add and change language resources. E.g. + ```js -import { i18n } from 'ohif-i18n'; +import { i18n } from '@ohif/i18n'; i18next.addResourceBundle('pt-BR', 'Buttons', { - 'Angle': 'Ângulo' + Angle: 'Ângulo', }); ``` ------- + +--- ### How to set a whole new language + To set a brand new language you can do it in two different ways: -* Opening a pull request for `ohif-i18n` and sharing the translation with the community. Please see [Contributing](#contributing-with-new-languages) section for further information -* Setting it only in your project or extension -To set it apart of `ohif-i18n`, follow this snippet: +- Opening a pull request for `@ohif/i18n` and sharing the translation with the + community. Please see [Contributing](#contributing-with-new-languages) section + for further information +- Setting it only in your project or extension + +To set it apart of `@ohif/i18n`, follow this snippet: + +File: myJsonFileWithLanguage.json // TODO - This example is a working in +progress -File: myJsonFileWithLanguage.json // TODO - This example is a working in progress ```json { - "prop1": "value1", - "prop2": "value2", - "prop3": "value3", - "prop4": "value4" + "en": { + "ns": { + "prop1": "value1", + "prop2": "value2", + "prop3": "value3", + "prop4": "value4" + } + } } ``` ```js -import { extendLanguage } from 'ohif-i18n'; +import { extendLanguage } from '@ohif/i18n'; import myJsonFileWithLanguage from './myJsonFileWithLanguage.json'; extendLanguage(myJsonFileWithLanguage); // TODO - This example is a working in progress ``` +## Debugging translations -#Debugging translations -#TODO - WIP +There are two environment variables responsible for debugging the translations: +`REACT_APP_I18N_DEBUG` and `REACT_APP_LANG`. + +For debugging, you can run the project as following: + +```bash +yarn; REACT_APP_I18N_DEBUG=true REACT_APP_LANG=es-MX yarn run dev +``` ### Contributing with new languages -Contributions of any kind are welcome! Please check the [instructions](https://docs.ohif.org/contributing.html). +Contributions of any kind are welcome! Please check the +[instructions](https://docs.ohif.org/contributing.html). From fe827b5b2ae6b00a4c12113e733c22d06326bc4f Mon Sep 17 00:00:00 2001 From: Rodrigo Antinarelli Date: Fri, 7 Jun 2019 19:53:49 -0300 Subject: [PATCH 2/6] add language detector lib --- extensions/ohif-i18n/package.json | 5 +++-- extensions/ohif-i18n/src/index.js | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/extensions/ohif-i18n/package.json b/extensions/ohif-i18n/package.json index 291e46352..812afabdc 100644 --- a/extensions/ohif-i18n/package.json +++ b/extensions/ohif-i18n/package.json @@ -17,9 +17,9 @@ "prepublishOnly": "npm run build" }, "peerDependencies": { + "i18next": "^15.1.3", "react": "^16.0.0", "react-dom": "^16.0.0", - "i18next": "^15.1.3", "react-i18next": "^10.11.0" }, "devDependencies": { @@ -51,7 +51,8 @@ "rollup-plugin-node-resolve": "^4.0.0", "rollup-plugin-peer-deps-external": "^2.2.0", "rollup-plugin-postcss": "^2.0.3", - "rollup-plugin-url": "^2.1.0" + "rollup-plugin-url": "^2.1.0", + "i18next-browser-languagedetector": "^3.0.1" }, "husky": { "hooks": { diff --git a/extensions/ohif-i18n/src/index.js b/extensions/ohif-i18n/src/index.js index 41d7362b8..69b2b9f9d 100755 --- a/extensions/ohif-i18n/src/index.js +++ b/extensions/ohif-i18n/src/index.js @@ -1,5 +1,6 @@ import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; +import LngDetector from 'i18next-browser-languagedetector'; const currentLanguage = process.env.REACT_APP_LANG || 'en-US'; const debugMode = !!( @@ -63,6 +64,7 @@ function addLocales(context) { let translate; i18n + .use(LngDetector) .use(initReactI18next) .init({ resources: getLocales(), From ee42257736993010d47dd2fc7bdae0e0bea7cfc9 Mon Sep 17 00:00:00 2001 From: Rodrigo Antinarelli Date: Fri, 7 Jun 2019 19:53:56 -0300 Subject: [PATCH 3/6] fix text --- extensions/ohif-i18n/src/locales/en/Header.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/ohif-i18n/src/locales/en/Header.json b/extensions/ohif-i18n/src/locales/en/Header.json index eefaf4542..c373fcb67 100644 --- a/extensions/ohif-i18n/src/locales/en/Header.json +++ b/extensions/ohif-i18n/src/locales/en/Header.json @@ -1,5 +1,5 @@ { - "INVESTIGATIONAL USE ONLY": "Preferences", + "INVESTIGATIONAL USE ONLY": "INVESTIGATIONAL USE ONLY", "Options": "Options", "About": "About", "Preferences": "Preferences", From ebb2e839250e323f647420d3f17ca2ee0bce2a37 Mon Sep 17 00:00:00 2001 From: Rodrigo Antinarelli Date: Fri, 7 Jun 2019 19:54:22 -0300 Subject: [PATCH 4/6] WIP - using yalc for react-viewerbase --- extensions/ohif-i18n/yarn.lock | 5 +++++ package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/extensions/ohif-i18n/yarn.lock b/extensions/ohif-i18n/yarn.lock index 6514cfc50..91116e353 100644 --- a/extensions/ohif-i18n/yarn.lock +++ b/extensions/ohif-i18n/yarn.lock @@ -2404,6 +2404,11 @@ husky@^1.3.1: run-node "^1.0.0" slash "^2.0.0" +i18next-browser-languagedetector@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-3.0.1.tgz#a47c43176e8412c91e808afb7c6eb5367649aa8e" + integrity sha512-WFjPLNPWl62uu07AHY2g+KsC9qz0tyMq+OZEB/H7N58YKL/JLiCz9U709gaR20Mule/Ppn+uyfVx5REJJjn1HA== + i18next@^15.1.3: version "15.1.3" resolved "https://registry.yarnpkg.com/i18next/-/i18next-15.1.3.tgz#f1984cbee0e3cb00cff9008b037264289ce8840a" diff --git a/package.json b/package.json index 51c7bdc09..aecf4cab9 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "react-resize-detector": "^3.4.0", "react-router": "^4.3.1", "react-router-dom": "^4.3.1", - "react-viewerbase": "0.7.0", + "react-viewerbase": "file:.yalc/react-viewerbase", "react-vtkjs-viewport": "^0.0.7", "redux": "^4.0.1", "redux-oidc": "3.1.x" From 5bbd6f14636e504bd0c975ed959cec340545fc8a Mon Sep 17 00:00:00 2001 From: Rodrigo Antinarelli Date: Fri, 7 Jun 2019 19:54:35 -0300 Subject: [PATCH 5/6] remove unused switch language buttons --- src/components/Header/Header.js | 35 +-------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js index 8b0c2d7cf..1fe1adcc0 100644 --- a/src/components/Header/Header.js +++ b/src/components/Header/Header.js @@ -2,7 +2,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { Link, withRouter } from 'react-router-dom'; import { Dropdown } from 'react-viewerbase'; -import i18n from '@ohif/i18n'; import { withTranslation } from 'react-i18next'; import './Header.css'; import OHIFLogo from '../OHIFLogo/OHIFLogo.js'; @@ -43,21 +42,13 @@ class Header extends Component { { title: t('About'), icon: { - name: 'info' + name: 'info', }, link: 'http://ohif.org', }, ]; } - changeLanguage(language) { - i18n.init({ - fallbackLng: language.substring(0, 2), - lng: language, - }); - this.loadOptions(); - } - render() { const { t } = this.props; return ( @@ -89,30 +80,6 @@ class Header extends Component {
{t('INVESTIGATIONAL USE ONLY')} - - - -
From ff382b02124df0dfc45c71d7792ac36a83998522 Mon Sep 17 00:00:00 2001 From: Rodrigo Antinarelli Date: Fri, 7 Jun 2019 19:54:49 -0300 Subject: [PATCH 6/6] Update yarn.lock --- yarn.lock | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index 287051e87..f19be5a3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1043,7 +1043,7 @@ react-vtkjs-viewport "^0.0.7" "@ohif/i18n@file:.yalc/@ohif/i18n": - version "0.0.2-4597feaf" + version "0.0.2-f8005bc6" dependencies: "@babel/runtime" "^7.2.0" classnames "^2.2.6" @@ -11788,10 +11788,8 @@ react-transition-group@^2.0.0, react-transition-group@^2.2.0: prop-types "^15.6.2" react-lifecycles-compat "^3.0.4" -react-viewerbase@0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/react-viewerbase/-/react-viewerbase-0.7.0.tgz#b0f48a0f003b849c280b8ca67927d4780c68b0dc" - integrity sha512-1VQXREKSsqxtOSSHRou0gjBODrSOjE8SBJ6/dHG0gPgdmeotOg68xPMKYf9K7fYyGZ6CDA7oVCAmdTE4SVYP5Q== +"react-viewerbase@file:.yalc/react-viewerbase": + version "0.2.17-1a0125ef" dependencies: "@babel/runtime" "7.2.0" classnames "2.2.6"