-
-
Notifications
You must be signed in to change notification settings - Fork 216
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add react internationalization (#10639)
create react internalization module using i18next with language detector see https://react.i18next.com/latest/using-with-hooks
- Loading branch information
1 parent
2454d7e
commit f8efc0d
Showing
19 changed files
with
354 additions
and
2 deletions.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
...ch/jhipster/lite/generator/client/react/i18n/application/ReactI18nApplicationService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package tech.jhipster.lite.generator.client.react.i18n.application; | ||
|
||
import org.springframework.stereotype.Service; | ||
import tech.jhipster.lite.generator.client.react.i18n.domain.ReactI18nModuleFactory; | ||
import tech.jhipster.lite.module.domain.JHipsterModule; | ||
import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; | ||
|
||
@Service | ||
public class ReactI18nApplicationService { | ||
|
||
private final ReactI18nModuleFactory factory; | ||
|
||
public ReactI18nApplicationService() { | ||
factory = new ReactI18nModuleFactory(); | ||
} | ||
|
||
public JHipsterModule buildModule(JHipsterModuleProperties properties) { | ||
return factory.buildModule(properties); | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
...in/java/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package tech.jhipster.lite.generator.client.react.i18n.domain; | ||
|
||
import static tech.jhipster.lite.module.domain.JHipsterModule.*; | ||
|
||
import tech.jhipster.lite.module.domain.JHipsterModule; | ||
import tech.jhipster.lite.module.domain.file.JHipsterSource; | ||
import tech.jhipster.lite.module.domain.packagejson.VersionSource; | ||
import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; | ||
import tech.jhipster.lite.shared.error.domain.Assert; | ||
|
||
public class ReactI18nModuleFactory { | ||
|
||
private static final JHipsterSource APP_SOURCE = from("client/react/i18n/src/main/webapp/app"); | ||
private static final JHipsterSource ASSETS_FR_SOURCE = from("client/react/i18n/src/main/webapp/assets/locales/fr"); | ||
private static final JHipsterSource ASSETS_EN_SOURCE = from("client/react/i18n/src/main/webapp/assets/locales/en"); | ||
|
||
private static final String INDEX = "src/main/webapp/"; | ||
private static final String INDEX_TEST = "src/test/webapp/unit/common/primary/app/"; | ||
|
||
public JHipsterModule buildModule(JHipsterModuleProperties properties) { | ||
Assert.notNull("properties", properties); | ||
|
||
//@formatter:off | ||
return moduleBuilder(properties) | ||
.packageJson() | ||
.addDependency(packageName("i18next"), VersionSource.COMMON) | ||
.addDependency(packageName("i18next-browser-languagedetector"), VersionSource.COMMON) | ||
.addDependency(packageName("i18next-http-backend"), VersionSource.COMMON) | ||
.addDependency(packageName("react-i18next"), VersionSource.REACT) | ||
.and() | ||
.files() | ||
.batch(APP_SOURCE, to(INDEX + "/app")) | ||
.addFile("i18n.ts") | ||
.and() | ||
.batch(ASSETS_EN_SOURCE, to(INDEX + "assets/locales/en/")) | ||
.addFile("translation.json") | ||
.and() | ||
.batch(ASSETS_FR_SOURCE, to(INDEX + "assets/locales/fr/")) | ||
.addFile("translation.json") | ||
.and() | ||
.and() | ||
.mandatoryReplacements() | ||
.in(path(INDEX + "app/common/primary/app/App.tsx")) | ||
.add(lineAfterText("import ReactLogo from '@assets/ReactLogo.png';"), "import { useTranslation } from 'react-i18next';") | ||
.add(lineBeforeText("return ("), properties.indentation().times(1) + "const { t } = useTranslation();" + LINE_BREAK) | ||
.add(lineAfterText("</h1>"), LINE_BREAK + | ||
properties.indentation().times(4) + "<p>{t('translationEnabled')}</p>") | ||
.and() | ||
.in(path(INDEX + "app/index.tsx")) | ||
.add(lineAfterText("import './index.css';"), "import './i18n';" + LINE_BREAK) | ||
.and() | ||
.in(path(INDEX_TEST + "App.spec.tsx")) | ||
.add(append(), LINE_BREAK + """ | ||
describe('App I18next', () => { | ||
it('renders with translation', () => { | ||
vi.mock('react-i18next', () => ({ | ||
useTranslation: () => { | ||
return { | ||
t: vi.fn().mockImplementation((_str: string) => 'Internationalization enabled'), | ||
i18n: { | ||
changeLanguage: () => new Promise(() => {}), | ||
}, | ||
}; | ||
}, | ||
})); | ||
render(<App />); | ||
const { getAllByText } = render(<App />); | ||
const title = getAllByText('Internationalization enabled'); | ||
expect(title).toBeTruthy(); | ||
}); | ||
});""" ) | ||
.and() | ||
.and() | ||
.build(); | ||
//@formatter:off | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
...lite/generator/client/react/i18n/infrastructure/primary/ReactI18nModuleConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package tech.jhipster.lite.generator.client.react.i18n.infrastructure.primary; | ||
|
||
import static tech.jhipster.lite.generator.slug.domain.JHLiteFeatureSlug.CLIENT_INTERNATIONALIZATION; | ||
import static tech.jhipster.lite.generator.slug.domain.JHLiteModuleSlug.REACT_CORE; | ||
import static tech.jhipster.lite.generator.slug.domain.JHLiteModuleSlug.REACT_I18N; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import tech.jhipster.lite.generator.client.react.i18n.application.ReactI18nApplicationService; | ||
import tech.jhipster.lite.module.domain.resource.JHipsterModuleOrganization; | ||
import tech.jhipster.lite.module.domain.resource.JHipsterModulePropertiesDefinition; | ||
import tech.jhipster.lite.module.domain.resource.JHipsterModuleResource; | ||
|
||
@Configuration | ||
class ReactI18nModuleConfiguration { | ||
|
||
@Bean | ||
JHipsterModuleResource i18nModule(ReactI18nApplicationService i18n) { | ||
return JHipsterModuleResource.builder() | ||
.slug(REACT_I18N) | ||
.propertiesDefinition(JHipsterModulePropertiesDefinition.builder().build()) | ||
.apiDoc("Frontend - React", "Add react internationalization") | ||
.organization(JHipsterModuleOrganization.builder().feature(CLIENT_INTERNATIONALIZATION).addDependency(REACT_CORE).build()) | ||
.tags("client", "react", "i18n") | ||
.factory(i18n::buildModule); | ||
} | ||
} |
2 changes: 2 additions & 0 deletions
2
src/main/java/tech/jhipster/lite/generator/client/react/i18n/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
@tech.jhipster.lite.BusinessContext | ||
package tech.jhipster.lite.generator.client.react.i18n; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
src/main/resources/generator/client/common/reacti18n/src/main/webapp/app/i18n.ts.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import i18n from 'i18next'; | ||
import { initReactI18next } from 'react-i18next'; | ||
|
||
import Backend from 'i18next-http-backend'; | ||
import LanguageDetector from 'i18next-browser-languagedetector'; | ||
|
||
i18n | ||
.use(Backend) | ||
.use(LanguageDetector) | ||
.use(initReactI18next) | ||
|
||
.init({ | ||
fallbackLng: 'en', | ||
debug: false, | ||
interpolation: { | ||
escapeValue: false, | ||
}, | ||
backend: { | ||
loadPath: '../assets/locales/{{ lng }}/{{ ns }}.json', | ||
}, | ||
}); | ||
|
||
export default i18n; |
3 changes: 3 additions & 0 deletions
3
.../resources/generator/client/common/reacti18n/src/main/webapp/assets/english.json.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"translationEnabled": "Internationalization enabled" | ||
} |
3 changes: 3 additions & 0 deletions
3
...n/resources/generator/client/common/reacti18n/src/main/webapp/assets/french.json.mustache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"translationEnabled": "Internationalisation activée" | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/resources/generator/client/react/i18n/src/main/webapp/app/i18n.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import i18n from 'i18next'; | ||
import { initReactI18next } from 'react-i18next'; | ||
|
||
import Backend from 'i18next-http-backend'; | ||
import LanguageDetector from 'i18next-browser-languagedetector'; | ||
|
||
i18n | ||
.use(Backend) | ||
.use(LanguageDetector) | ||
.use(initReactI18next) | ||
|
||
.init({ | ||
fallbackLng: 'en', | ||
debug: false, | ||
|
||
interpolation: { | ||
escapeValue: false, | ||
}, | ||
backend: { | ||
loadPath: '../assets/locales/{{ lng }}/{{ ns }}.json', | ||
}, | ||
}); | ||
|
||
export default i18n; |
3 changes: 3 additions & 0 deletions
3
.../resources/generator/client/react/i18n/src/main/webapp/assets/locales/en/translation.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"translationEnabled": "Internationalization enabled" | ||
} |
3 changes: 3 additions & 0 deletions
3
.../resources/generator/client/react/i18n/src/main/webapp/assets/locales/fr/translation.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"translationEnabled": "Internationalisation activée" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Feature: React i18n | ||
|
||
Scenario: Should apply react i18n module to react | ||
When I apply modules to default project | ||
| init | | ||
| react-core | | ||
| react-i18next | | ||
Then I should have files in "src/main/webapp/app" | ||
| i18n.ts | | ||
And I should have files in "src/main/webapp/assets/locales/en" | ||
| translation.json | | ||
And I should have files in "src/main/webapp/assets/locales/fr" | ||
| translation.json | |
104 changes: 104 additions & 0 deletions
104
...ava/tech/jhipster/lite/generator/client/react/i18n/domain/ReactI18nModuleFactoryTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package tech.jhipster.lite.generator.client.react.i18n.domain; | ||
|
||
import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.*; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import tech.jhipster.lite.TestFileUtils; | ||
import tech.jhipster.lite.UnitTest; | ||
import tech.jhipster.lite.module.domain.JHipsterModule; | ||
import tech.jhipster.lite.module.domain.JHipsterModulesFixture; | ||
|
||
@UnitTest | ||
public class ReactI18nModuleFactoryTest { | ||
|
||
public static final ReactI18nModuleFactory factory = new ReactI18nModuleFactory(); | ||
|
||
private static final String APP_TSX = "src/main/webapp/app/common/primary/app/App.tsx"; | ||
|
||
@Test | ||
void shouldBuildI18nModule() { | ||
JHipsterModule module = factory.buildModule( | ||
JHipsterModulesFixture.propertiesBuilder(TestFileUtils.tmpDirForTest()).projectBaseName("jhipster").build() | ||
); | ||
|
||
JHipsterModuleAsserter asserter = assertThatModuleWithFiles(module, packageJsonFile(), app(), appTest(), index()); | ||
|
||
asserter | ||
.hasFile("package.json") | ||
.containing(nodeDependency("i18next")) | ||
.containing(nodeDependency("i18next-browser-languagedetector")) | ||
.containing(nodeDependency("i18next-http-backend")) | ||
.containing(nodeDependency("react-i18next")) | ||
.and() | ||
.hasFile("src/main/webapp/app/i18n.ts") | ||
.containing( | ||
""" | ||
import i18n from 'i18next'; | ||
import { initReactI18next } from 'react-i18next'; | ||
import Backend from 'i18next-http-backend'; | ||
import LanguageDetector from 'i18next-browser-languagedetector'; | ||
i18n | ||
.use(Backend) | ||
.use(LanguageDetector) | ||
.use(initReactI18next) | ||
.init({ | ||
fallbackLng: 'en', | ||
debug: false, | ||
interpolation: { | ||
escapeValue: false, | ||
}, | ||
backend: { | ||
loadPath: '../assets/locales/{{ lng }}/{{ ns }}.json', | ||
}, | ||
}); | ||
export default i18n; | ||
""" | ||
) | ||
.and() | ||
.hasFile("src/main/webapp/app/index.tsx") | ||
.containing("import './i18n'") | ||
.and() | ||
.hasFile("src/main/webapp/app/common/primary/app/App.tsx") | ||
.containing("import { useTranslation } from 'react-i18next") | ||
.containing("const { t } = useTranslation();") | ||
.containing("{t('translationEnabled')}") | ||
.and() | ||
.hasFile("src/main/webapp/assets/locales/en/translation.json") | ||
.containing( | ||
""" | ||
{ | ||
"translationEnabled": "Internationalization enabled" | ||
} | ||
""" | ||
) | ||
.and() | ||
.hasFile("src/main/webapp/assets/locales/fr/translation.json") | ||
.containing( | ||
""" | ||
{ | ||
"translationEnabled": "Internationalisation activée" | ||
} | ||
""" | ||
) | ||
.and() | ||
.hasFile("src/test/webapp/unit/common/primary/app/App.spec.tsx") | ||
.containing("describe('App I18next', () => {"); | ||
} | ||
|
||
private ModuleFile app() { | ||
return file("src/test/resources/projects/react-app/App.tsx", APP_TSX); | ||
} | ||
|
||
private ModuleFile appTest() { | ||
return file("src/test/resources/projects/react-app/App.spec.tsx", "src/test/webapp/unit/common/primary/app/App.spec.tsx"); | ||
} | ||
|
||
private ModuleFile index() { | ||
return file("src/test/resources/projects/react-app/index.tsx", "src/main/webapp/app/index.tsx"); | ||
} | ||
} |
Oops, something went wrong.