mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-19 17:14:57 +00:00
[ACS-5629] enhanced way of providing translations (#8763)
* enhanced way providing translations * update documentation * update documentation * test fixes * try add missing module import * inject i18n to core module to cause the setup
This commit is contained in:
parent
d70f689e06
commit
1a4d7ba008
demo-shell/src/app
docs/core/services
lib
content-services/src/lib
core/src/lib
insights/src/lib
process-services-cloud/src/lib
process-services/src/lib
@ -24,11 +24,11 @@ import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import {
|
||||
AppConfigService,
|
||||
TRANSLATION_PROVIDER,
|
||||
DebugAppConfigService,
|
||||
CoreModule,
|
||||
CoreAutomationService,
|
||||
AuthModule
|
||||
AuthModule,
|
||||
provideTranslations
|
||||
} from '@alfresco/adf-core';
|
||||
import { ExtensionsModule } from '@alfresco/adf-extensions';
|
||||
import { AppComponent } from './app.component';
|
||||
@ -211,22 +211,8 @@ registerLocaleData(localeSv);
|
||||
],
|
||||
providers: [
|
||||
{ provide: AppConfigService, useClass: DebugAppConfigService }, // not use this service in production
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'app',
|
||||
source: 'resources'
|
||||
}
|
||||
},
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'lazy-loading',
|
||||
source: 'resources/lazy-loading'
|
||||
}
|
||||
},
|
||||
provideTranslations('app', 'resources'),
|
||||
provideTranslations('lazy-loading', 'resources/lazy-loading'),
|
||||
AppNotificationsService,
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
|
@ -62,7 +62,7 @@ this.trans.get(
|
||||
total: "122"
|
||||
}
|
||||
).subscribe(translation => {
|
||||
this.translatedText = translation;
|
||||
this.translatedText = translation;
|
||||
});
|
||||
```
|
||||
|
||||
@ -79,16 +79,21 @@ general format of the path to this folder will be:
|
||||
If you wanted English and French translations then you would add
|
||||
`en.json` and `fr.json` files into the `i18n` folder and add your new keys:
|
||||
|
||||
// en.json
|
||||
**en.json**
|
||||
|
||||
...
|
||||
"WELCOME_MESSAGE": "Welcome!"
|
||||
...
|
||||
```json
|
||||
{
|
||||
"WELCOME_MESSAGE": "Welcome!"
|
||||
}
|
||||
```
|
||||
|
||||
// fr.json
|
||||
...
|
||||
"WELCOME_MESSAGE": "Bienvenue !"
|
||||
...
|
||||
**fr.json**
|
||||
|
||||
```json
|
||||
{
|
||||
"WELCOME_MESSAGE": "Bienvenue !"
|
||||
}
|
||||
```
|
||||
|
||||
The files follow the same hierarchical key:value JSON format as the built-in translations.
|
||||
You can add new keys to your local files or redefine existing keys but the built-in definitions
|
||||
@ -97,66 +102,53 @@ look like the following:
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "my app",
|
||||
"LOGIN": {
|
||||
"LABEL": {
|
||||
"LOGIN": "Custom Sign In"
|
||||
}
|
||||
}
|
||||
"title": "my app",
|
||||
"LOGIN": {
|
||||
"LABEL": {
|
||||
"LOGIN": "Custom Sign In"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To enable the new translations in your app, you also need to register them in your
|
||||
`app.module.ts` file. Import `TRANSLATION_PROVIDER` and add the path of your
|
||||
translations folder to the `providers`:
|
||||
To enable the new translations in your app, you also need to register them in your `app.module.ts` file using `provideTranslations` api:
|
||||
|
||||
```ts
|
||||
// Other imports...
|
||||
|
||||
import { TRANSLATION_PROVIDER } from "@alfresco/adf-core";
|
||||
|
||||
...
|
||||
import { provideTranslations } from "@alfresco/adf-core";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
...
|
||||
],
|
||||
declarations: [
|
||||
...
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'my-translations',
|
||||
source: 'assets/my-translations'
|
||||
}
|
||||
}
|
||||
...
|
||||
providers: [
|
||||
provideTranslations('my-translations', 'assets/my-translations')
|
||||
]
|
||||
})
|
||||
export class MyModule {}
|
||||
```
|
||||
|
||||
You can now use your new keys in your component:
|
||||
|
||||
```ts
|
||||
...
|
||||
ngOnInit() {
|
||||
this.trans.use("fr");
|
||||
|
||||
this.trans.get("WELCOME_MESSAGE").subscribe(translation => {
|
||||
this.translatedText = translation;
|
||||
});
|
||||
}
|
||||
...
|
||||
export class MyComponent implements OnInit {
|
||||
translateService = inject(TranslationService);
|
||||
translatedText = '';
|
||||
|
||||
ngOnInit() {
|
||||
this.translateService.use("fr");
|
||||
this.translatedText = this.translateService.instant('WELCOME_MESSAGE');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note: the `source` property points to the web application root. Ensure you have
|
||||
webpack correctly set up to copy all the i18n files at compile time.
|
||||
Note: the `source` property points to the web application root.
|
||||
Do not forget to configure your Angular application to copy the newly created files to the build output, for example:
|
||||
|
||||
```text
|
||||
index.html
|
||||
assets/ng2-alfresco-core/i18n/en.json
|
||||
...
|
||||
**angular.json**
|
||||
|
||||
```json
|
||||
{
|
||||
"glob": "**/*",
|
||||
"input": "lib/core/src/lib/i18n",
|
||||
"output": "/assets/adf-core/i18n"
|
||||
}
|
||||
```
|
||||
|
||||
You can register as many entries as you like.
|
||||
@ -180,4 +172,4 @@ class MyComponent {
|
||||
|
||||
## See Also
|
||||
|
||||
- [Internationalization](../../user-guide/internationalization.md)
|
||||
- [Internationalization](../../user-guide/internationalization.md)
|
||||
|
@ -18,7 +18,7 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, ModuleWithProviders, APP_INITIALIZER } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CoreModule, TRANSLATION_PROVIDER, SearchTextModule } from '@alfresco/adf-core';
|
||||
import { CoreModule, SearchTextModule, provideTranslations } from '@alfresco/adf-core';
|
||||
|
||||
import { MaterialModule } from './material.module';
|
||||
|
||||
@ -89,14 +89,7 @@ import { CategoriesModule } from './category/category.module';
|
||||
CategoriesModule
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-content-services',
|
||||
source: 'assets/adf-content-services'
|
||||
}
|
||||
}
|
||||
provideTranslations('adf-content-services', 'assets/adf-content-services')
|
||||
],
|
||||
exports: [
|
||||
ContentPipeModule,
|
||||
@ -134,14 +127,7 @@ export class ContentModule {
|
||||
return {
|
||||
ngModule: ContentModule,
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-content-services',
|
||||
source: 'assets/adf-content-services'
|
||||
}
|
||||
},
|
||||
provideTranslations('adf-content-services', 'assets/adf-content-services'),
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: versionCompatibilityFactory,
|
||||
|
@ -19,7 +19,7 @@ import { NgModule } from '@angular/core';
|
||||
import { CoreModule } from '../core.module';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { TRANSLATION_PROVIDER } from '../translation/translation.service';
|
||||
import { provideTranslations } from '../translation/translation.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@ -28,14 +28,7 @@ import { TRANSLATION_PROVIDER } from '../translation/translation.service';
|
||||
BrowserAnimationsModule
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-core',
|
||||
source: 'assets/adf-core'
|
||||
}
|
||||
}
|
||||
provideTranslations('adf-core', 'assets/adf-core')
|
||||
]
|
||||
})
|
||||
export class CoreStoryModule { }
|
||||
|
@ -21,7 +21,7 @@ import { getTestBed, TestBed } from '@angular/core/testing';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { TranslateLoaderService } from './translate-loader.service';
|
||||
import { TRANSLATION_PROVIDER, TranslationService } from './translation.service';
|
||||
import { provideTranslations, TranslationService } from './translation.service';
|
||||
import { AppConfigService } from '../app-config/app-config.service';
|
||||
import { AppConfigServiceMock } from '../common/mock/app-config.service.mock';
|
||||
import { AlfrescoApiService } from '../services/alfresco-api.service';
|
||||
@ -47,14 +47,7 @@ describe('TranslationService', () => {
|
||||
providers: [
|
||||
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock },
|
||||
{ provide: AppConfigService, useClass: AppConfigServiceMock },
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: '@alfresco/adf-core',
|
||||
source: 'assets/ng2-alfresco-core'
|
||||
}
|
||||
}
|
||||
provideTranslations('@alfresco/adf-core', 'assets/ng2-alfresco-core')
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -28,6 +28,24 @@ export interface TranslationProvider {
|
||||
source: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate translation provider
|
||||
*
|
||||
* @param id Unique identifier
|
||||
* @param path Path to translation files
|
||||
* @returns Provider
|
||||
*/
|
||||
export function provideTranslations(id: string, path: string) {
|
||||
return {
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: id,
|
||||
source: path
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
|
@ -18,7 +18,7 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CoreModule, TRANSLATION_PROVIDER } from '@alfresco/adf-core';
|
||||
import { CoreModule, provideTranslations } from '@alfresco/adf-core';
|
||||
|
||||
import { DiagramsModule } from './diagram/diagram.module';
|
||||
import { AnalyticsProcessModule } from './analytics-process/analytics-process.module';
|
||||
@ -45,14 +45,7 @@ export class InsightsModule {
|
||||
return {
|
||||
ngModule: InsightsModule,
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-insights',
|
||||
source: 'assets/adf-insights'
|
||||
}
|
||||
}
|
||||
provideTranslations('adf-insights', 'assets/adf-insights')
|
||||
]
|
||||
};
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import {
|
||||
FormModel,
|
||||
FormOutcomeEvent,
|
||||
FormOutcomeModel, FormRenderingService, FormService,
|
||||
TRANSLATION_PROVIDER, UploadWidgetContentLinkModel, WidgetVisibilityService
|
||||
UploadWidgetContentLinkModel, WidgetVisibilityService, provideTranslations
|
||||
} from '@alfresco/adf-core';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
import { ESCAPE } from '@angular/cdk/keycodes';
|
||||
@ -54,6 +54,7 @@ import { FormCloudRepresentation } from '../models/form-cloud-representation.mod
|
||||
import { FormCloudService } from '../services/form-cloud.service';
|
||||
import { CloudFormRenderingService } from './cloud-form-rendering.service';
|
||||
import { FormCloudComponent } from './form-cloud.component';
|
||||
import { ProcessServicesCloudModule } from '../../process-services-cloud.module';
|
||||
|
||||
const mockOauth2Auth: any = {
|
||||
oauth2Auth: {
|
||||
@ -1152,17 +1153,11 @@ describe('Multilingual Form', () => {
|
||||
imports: [
|
||||
NoopAnimationsModule,
|
||||
TranslateModule.forRoot(),
|
||||
CoreModule.forRoot()
|
||||
CoreModule.forRoot(),
|
||||
ProcessServicesCloudModule.forRoot()
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'app',
|
||||
source: 'resources'
|
||||
}
|
||||
}
|
||||
provideTranslations('app', 'resources')
|
||||
]
|
||||
});
|
||||
translateService = TestBed.inject(TranslateService);
|
||||
@ -1184,20 +1179,20 @@ describe('Multilingual Form', () => {
|
||||
formComponent.ngOnChanges({ appName: new SimpleChange(null, appName, true) });
|
||||
expect(formCloudService.getForm).toHaveBeenCalledWith(appName, formId, 1);
|
||||
|
||||
fixture.ngZone.run(() => translateService.use('fr'));
|
||||
await translateService.use('fr').toPromise();
|
||||
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(getLabelValue('textField')).toEqual('Champ de texte');
|
||||
expect(getLabelValue('fildUploadField')).toEqual('Téléchargement de fichiers');
|
||||
expect(getLabelValue('dateField')).toEqual('Champ de date (D-M-YYYY)');
|
||||
expect(getLabelValue('amountField')).toEqual('Champ Montant');
|
||||
|
||||
fixture.ngZone.run(() => translateService.use('en'));
|
||||
await translateService.use('en').toPromise();
|
||||
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(getLabelValue('textField')).toEqual('Text field');
|
||||
expect(getLabelValue('fildUploadField')).toEqual('File Upload');
|
||||
@ -1237,14 +1232,7 @@ describe('retrieve metadata on submit', () => {
|
||||
FormCloudModule
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'app',
|
||||
source: 'resources'
|
||||
}
|
||||
},
|
||||
provideTranslations('app', 'resources'),
|
||||
{
|
||||
provide: VersionCompatibilityService,
|
||||
useValue: {}
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { TRANSLATION_PROVIDER, CoreModule, FormRenderingService } from '@alfresco/adf-core';
|
||||
import { CoreModule, FormRenderingService, provideTranslations } from '@alfresco/adf-core';
|
||||
import { AppListCloudModule } from './app/app-list-cloud.module';
|
||||
import { TaskCloudModule } from './task/task-cloud.module';
|
||||
import { ProcessCloudModule } from './process/process-cloud.module';
|
||||
@ -52,14 +52,7 @@ import { RichTextEditorModule } from './rich-text-editor/rich-text-editor.module
|
||||
RichTextEditorModule
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-process-services-cloud',
|
||||
source: 'assets/adf-process-services-cloud'
|
||||
}
|
||||
}
|
||||
provideTranslations('adf-process-services-cloud', 'assets/adf-process-services-cloud')
|
||||
],
|
||||
exports: [
|
||||
AppListCloudModule,
|
||||
@ -81,14 +74,7 @@ export class ProcessServicesCloudModule {
|
||||
return {
|
||||
ngModule: ProcessServicesCloudModule,
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-process-services-cloud',
|
||||
source: 'assets/adf-process-services-cloud'
|
||||
}
|
||||
},
|
||||
provideTranslations('adf-process-services-cloud', 'assets/adf-process-services-cloud'),
|
||||
{ provide: PROCESS_FILTERS_SERVICE_TOKEN, useExisting: filterPreferenceServiceInstance ?? LocalPreferenceCloudService },
|
||||
{ provide: TASK_FILTERS_SERVICE_TOKEN, useExisting: filterPreferenceServiceInstance ?? LocalPreferenceCloudService },
|
||||
{ provide: PROCESS_LISTS_PREFERENCES_SERVICE_TOKEN, useExisting: listPreferenceServiceInstance ?? LocalPreferenceCloudService },
|
||||
|
@ -16,25 +16,20 @@
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CoreModule, TRANSLATION_PROVIDER } from '@alfresco/adf-core';
|
||||
import { CoreModule, provideTranslations } from '@alfresco/adf-core';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ProcessServicesCloudModule } from '../process-services-cloud.module';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserAnimationsModule,
|
||||
TranslateModule.forRoot(),
|
||||
CoreModule.forRoot(),
|
||||
BrowserAnimationsModule
|
||||
ProcessServicesCloudModule.forRoot()
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-process-services-cloud',
|
||||
source: 'assets/adf-process-services-cloud'
|
||||
}
|
||||
}
|
||||
provideTranslations('adf-process-services-cloud', 'assets/adf-process-services-cloud')
|
||||
]
|
||||
})
|
||||
export class ProcessServicesCloudStoryModule { }
|
||||
|
@ -18,7 +18,7 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule, ModuleWithProviders } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { CoreModule, TRANSLATION_PROVIDER, FormRenderingService } from '@alfresco/adf-core';
|
||||
import { CoreModule, FormRenderingService, provideTranslations } from '@alfresco/adf-core';
|
||||
|
||||
import { MaterialModule } from './material.module';
|
||||
|
||||
@ -53,14 +53,7 @@ import { ProcessUserInfoModule } from './process-user-info/process-user-info.mod
|
||||
ProcessServicesPipeModule
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-process-services',
|
||||
source: 'assets/adf-process-services'
|
||||
}
|
||||
}
|
||||
provideTranslations('adf-process-services', 'assets/adf-process-services')
|
||||
],
|
||||
exports: [
|
||||
CommonModule,
|
||||
@ -83,14 +76,7 @@ export class ProcessModule {
|
||||
return {
|
||||
ngModule: ProcessModule,
|
||||
providers: [
|
||||
{
|
||||
provide: TRANSLATION_PROVIDER,
|
||||
multi: true,
|
||||
useValue: {
|
||||
name: 'adf-process-services',
|
||||
source: 'assets/adf-process-services'
|
||||
}
|
||||
},
|
||||
provideTranslations('adf-process-services', 'assets/adf-process-services'),
|
||||
FormRenderingService,
|
||||
{ provide: FormRenderingService, useClass: ProcessFormRenderingService }
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user