forked from jhipster/jhipster-lite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create react internalization module using i18next 23.14.0 with language detector see https://react.i18next.com/latest/using-with-hooks Fix jhipster#10413
- Loading branch information
1 parent
cb76699
commit fd66a56
Showing
14 changed files
with
294 additions
and
1 deletion.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
...ipster/lite/generator/client/tools/reacti18n/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.tools.reacti18n.application; | ||
|
||
import org.springframework.stereotype.Service; | ||
import tech.jhipster.lite.generator.client.tools.reacti18n.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); | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
...va/tech/jhipster/lite/generator/client/tools/reacti18n/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,73 @@ | ||
package tech.jhipster.lite.generator.client.tools.reacti18n.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/common/reacti18n/src/main/webapp/app"); | ||
private static final JHipsterSource ASSETS_SOURCE = from("client/common/reacti18n/src/main/webapp/assets"); | ||
|
||
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.REACT) | ||
.addDependency(packageName("i18next-browser-languagedetector"), VersionSource.REACT) | ||
.addDependency(packageName("i18next-http-backend"), VersionSource.REACT) | ||
.addDependency(packageName("react-i18next"), VersionSource.REACT) | ||
.and() | ||
.files() | ||
.add(APP_SOURCE.template("i18n.ts"), to(INDEX + "app/i18n.ts")) | ||
.add(ASSETS_SOURCE.template("english.json"), to(INDEX + "assets/locales/en/translation.json")) | ||
.add(ASSETS_SOURCE.template("french.json"), to(INDEX + "assets/locales/fr/translation.json")) | ||
.and() | ||
.mandatoryReplacements() | ||
.in(path(INDEX + "app/common/primary/app/App.tsx")) | ||
.add(lineAfterText("import ReactLogo from '@assets/ReactLogo.png';"), "import { useTranslation } from 'react-i18next';" + LINE_BREAK) | ||
.add(lineBeforeText("return ("), properties.indentation().times(1) + "const { t } = useTranslation();" + LINE_BREAK) | ||
.add(lineAfterText("</h1>"), LINE_BREAK + | ||
properties.indentation().times(4) + "<p>" + LINE_BREAK + | ||
properties.indentation().times(5) + "{t(\"translationEnabled\")}" + LINE_BREAK + | ||
properties.indentation().times(4) + "</p>" + LINE_BREAK) | ||
.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
...generator/client/tools/reacti18n/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.tools.reacti18n.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.tools.reacti18n.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 | ||
public class ReactI18nModuleConfiguration { | ||
|
||
@Bean | ||
JHipsterModuleResource i18nModule(ReactI18nApplicationService i18n) { | ||
return JHipsterModuleResource.builder() | ||
.slug(REACT_I18N) | ||
.propertiesDefinition(JHipsterModulePropertiesDefinition.builder().build()) | ||
.apiDoc("react i18n", "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/tools/reacti18n/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.tools.reacti18n; |
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
25 changes: 25 additions & 0 deletions
25
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,25 @@ | ||
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" | ||
} |
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 | |
105 changes: 105 additions & 0 deletions
105
...ech/jhipster/lite/generator/client/tools/reacti18n/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,105 @@ | ||
package tech.jhipster.lite.generator.client.tools.reacti18n.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"); | ||
} | ||
} |
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,12 @@ | ||
import { render } from '@testing-library/react'; | ||
import { describe, it } from 'vitest'; | ||
|
||
import App from '@/common/primary/app/App'; | ||
|
||
describe('App tests', () => { | ||
it('renders without crashing', () => { | ||
const { getByText } = render(<App />); | ||
const title = getByText('React + TypeScript + Vite'); | ||
expect(title).toBeTruthy(); | ||
}); | ||
}); |