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 -
{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'; - -{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'; + +
-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).
diff --git a/extensions/ohif-i18n/package.json b/extensions/ohif-i18n/package.json
index 90059c7f8..8bdc9a1af 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(),
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",
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/extensions/ohif-vtk-extension/package.json b/extensions/ohif-vtk-extension/package.json
index ea8ccfcbd..492862ec7 100644
--- a/extensions/ohif-vtk-extension/package.json
+++ b/extensions/ohif-vtk-extension/package.json
@@ -41,7 +41,6 @@
"@babel/plugin-transform-runtime": "^7.2.0",
"@babel/preset-env": "^7.2.3",
"@babel/preset-react": "^7.0.0",
- "@ohif/i18n": "0.0.1-rc-001",
"babel-eslint": "^10.0.1",
"cross-env": "^5.2.0",
"eslint": "5.13.0",
@@ -58,6 +57,7 @@
"rollup": "^1.1.2",
"rollup-plugin-babel": "^4.2.0",
"rollup-plugin-commonjs": "^9.2.0",
+ "rollup-plugin-copy": "^2.0.1",
"rollup-plugin-node-builtins": "^2.1.2",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-peer-deps-external": "^2.2.0",
@@ -93,7 +93,6 @@
},
"dependencies": {
"@babel/runtime": "^7.2.0",
- "@ohif/extension-vtk": "file:.yalc/@ohif/extension-vtk",
"classnames": "^2.2.6",
"react-vtkjs-viewport": "^0.0.7"
}
diff --git a/extensions/ohif-vtk-extension/rollup.config.js b/extensions/ohif-vtk-extension/rollup.config.js
index dcbddc988..66a4b2b0d 100644
--- a/extensions/ohif-vtk-extension/rollup.config.js
+++ b/extensions/ohif-vtk-extension/rollup.config.js
@@ -6,6 +6,7 @@ import pkg from './package.json';
import postcss from 'rollup-plugin-postcss';
import resolve from 'rollup-plugin-node-resolve';
import url from 'rollup-plugin-url';
+import copy from 'rollup-plugin-copy';
// Deal with https://github.com/rollup/rollup-plugin-commonjs/issues/297
@@ -24,7 +25,8 @@ const globals = {
dcmjs: 'dcmjs',
'dicom-parser': 'dicomParser',
'ohif-core': 'OHIF',
- hammerjs: 'Hammer'
+ hammerjs: 'Hammer',
+ '@ohif/i18n': 'i18n'
};
export default {
@@ -56,6 +58,10 @@ export default {
externalHelpers: true,
runtimeHelpers: true
}),
+ copy({
+ targets: ['src/locales'],
+ outputFolder: 'dist',
+ }),
resolve(),
commonjs({
include: ['node_modules/**', '.yalc/**'],
diff --git a/extensions/ohif-vtk-extension/yarn.lock b/extensions/ohif-vtk-extension/yarn.lock
index 26c0bb834..a109a0e37 100644
--- a/extensions/ohif-vtk-extension/yarn.lock
+++ b/extensions/ohif-vtk-extension/yarn.lock
@@ -727,21 +727,6 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
-"@ohif/extension-vtk@file:.yalc/@ohif/extension-vtk":
- version "0.0.3-9acf58f8"
- dependencies:
- "@babel/runtime" "^7.2.0"
- classnames "^2.2.6"
- react-vtkjs-viewport "^0.0.7"
-
-"@ohif/i18n@0.0.1-rc-001":
- version "0.0.1-rc-001"
- resolved "https://registry.yarnpkg.com/@ohif/i18n/-/i18n-0.0.1-rc-001.tgz#47286daa1411efb5f0219f0310484c8919bfe607"
- integrity sha512-CJ9wqd15DpJ6adVMyXkyqQqcRZgSnMWJ7L3WyUpMqf66CvAFKzCUuckyiFeCupIq8ZGv7w4jaADSYKrLcpviUw==
- dependencies:
- "@babel/runtime" "^7.2.0"
- classnames "^2.2.6"
-
"@samverschueren/stream-to-observable@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f"
@@ -3009,7 +2994,7 @@ from2@^2.1.0:
inherits "^2.0.1"
readable-stream "^2.0.0"
-fs-extra@^7.0.0:
+fs-extra@^7.0.0, fs-extra@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
@@ -3978,6 +3963,13 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
+is-plain-object@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928"
+ integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==
+ dependencies:
+ isobject "^4.0.0"
+
is-promise@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
@@ -4091,6 +4083,11 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
+isobject@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
+ integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
+
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@@ -7056,6 +7053,15 @@ rollup-plugin-commonjs@^9.2.0:
resolve "^1.8.1"
rollup-pluginutils "^2.3.3"
+rollup-plugin-copy@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/rollup-plugin-copy/-/rollup-plugin-copy-2.0.1.tgz#2a45e45be84a0d4054d1774604044e7f7581fdae"
+ integrity sha512-IE+Ob5k1Pi/DLi8SlFcf9jN1m2p0ovIwMuz0GM5NeQeV14puW/bCUpmXlqVtQVy+ErXOhZEeBaqinJ0xnJdxKg==
+ dependencies:
+ chalk "^2.4.2"
+ fs-extra "^7.0.1"
+ is-plain-object "^3.0.0"
+
rollup-plugin-node-builtins@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/rollup-plugin-node-builtins/-/rollup-plugin-node-builtins-2.1.2.tgz#24a1fed4a43257b6b64371d8abc6ce1ab14597e9"
diff --git a/package.json b/package.json
index aecf4cab9..5eb2012f2 100644
--- a/package.json
+++ b/package.json
@@ -69,8 +69,8 @@
"@babel/runtime": "^7.2.0",
"@ohif/extension-cornerstone": "0.0.34",
"@ohif/extension-dicom-microscopy": "0.0.6",
- "@ohif/extension-vtk": "0.0.2",
- "@ohif/i18n": "file:.yalc/@ohif/i18n",
+ "@ohif/extension-vtk": "file:.yalc/@ohif/extension-vtk",
+ "@ohif/i18n": "0.0.1-rc-001",
"classnames": "^2.2.6",
"cornerstone-core": "^2.2.8",
"cornerstone-math": "^0.1.8",
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 {