diff --git a/package.json b/package.json index f9019eb3fd..1ceea4fcbd 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "js.clone": "0.0.3", "methods": "~1.1.2", "morgan": "^1.7.0", + "ng2-translate": "~4.0.1", "preboot": "~4.5.2", "rxjs": "5.0.0-beta.12", "webfontloader": "^1.6.26", @@ -82,7 +83,7 @@ "awesome-typescript-loader": "^2.2.4", "codelyzer": "1.0.0-beta.3", "cookie-parser": "^1.4.3", - "copy-webpack-plugin": "4.0.1", + "copy-webpack-plugin": "~4.0.1", "express-interceptor": "^1.2.0", "iltorb": "^1.0.13", "imports-loader": "^0.6.5", diff --git a/resources/i18n/en.json b/resources/i18n/en.json new file mode 100644 index 0000000000..26237a935d --- /dev/null +++ b/resources/i18n/en.json @@ -0,0 +1,13 @@ +{ + "title": "DSpace Universal", + + "nav": { + "home": "Home" + }, + + "example": { + "with": { + "data": "{{greeting}}, {{recipient}}!" + } + } +} diff --git a/src/app/app.component.css b/src/app/app.component.css index e69de29bb2..fba0342027 100644 --- a/src/app/app.component.css +++ b/src/app/app.component.css @@ -0,0 +1 @@ +header nav.navbar{border-radius:0rem}header nav.navbar .navbar-toggler{float:right}header nav.navbar .navbar-toggler:hover{cursor:pointer} diff --git a/src/app/app.component.html b/src/app/app.component.html index b7939592d7..83a269739f 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -5,19 +5,22 @@
- DSpace + {{ 'title' | translate }}
+
+

{{ 'example.with.data' | translate:data }}

+

{{ example }}

diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 3f0026a293..2846624aa8 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,7 +1,8 @@ import { Component, HostListener, Input, ChangeDetectionStrategy, ViewEncapsulation, OnDestroy, OnInit } from '@angular/core'; - import { Event, NavigationEnd, Router } from '@angular/router'; +import { TranslateService } from 'ng2-translate'; + @Component({ changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.Emulated, @@ -17,12 +18,22 @@ export class AppComponent implements OnDestroy, OnInit { private routerSubscription: any; - constructor(private router: Router) { - this.collapse(); + + private translateSubscription: any; + + example: string; + + data: any = { + greeting: 'Hello', + recipient: 'World' } - @HostListener('window:resize', ['$event']) - private onResize(event): void { + constructor(public translate: TranslateService, private router: Router) { + // this language will be used as a fallback when a translation isn't found in the current language + translate.setDefaultLang('en'); + // the lang to use, if the lang isn't available, it will use the current loader to get them + translate.use('en'); + this.collapse(); } @@ -32,12 +43,23 @@ export class AppComponent implements OnDestroy, OnInit { this.collapse(); } }); + this.translateSubscription = this.translate.get('example.with.data', { greeting: 'Hello', recipient: 'DSpace' }).subscribe((translation: string) => { + this.example = translation; + }); } ngOnDestroy() { if (this.routerSubscription) { this.routerSubscription.unsubscribe(); } + if (this.translateSubscription) { + this.translateSubscription.unsubscribe(); + } + } + + @HostListener('window:resize', ['$event']) + private onResize(event): void { + this.collapse(); } private collapse(): void { diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 5bf60b85d4..91b9d1b87d 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -4,6 +4,7 @@ import { RouterModule } from '@angular/router'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateModule } from 'ng2-translate/ng2-translate'; import { ApiService } from './api.service'; import { ModelService } from './model/model.service'; @@ -12,6 +13,7 @@ const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here CommonModule, RouterModule, + TranslateModule, FormsModule, ReactiveFormsModule, NgbModule diff --git a/src/browser.module.ts b/src/browser.module.ts index d86e0bae4a..20c87fd924 100755 --- a/src/browser.module.ts +++ b/src/browser.module.ts @@ -1,10 +1,12 @@ import { NgModule } from '@angular/core'; +import { Http } from '@angular/http'; import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; import { UniversalModule, isBrowser, isNode, AUTO_PREBOOT } from 'angular2-universal/browser'; // for AoT we need to manually split universal packages import { IdlePreload, IdlePreloadModule } from '@angularclass/idle-preload'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateLoader, TranslateModule, TranslateStaticLoader } from 'ng2-translate'; import { AppModule, AppComponent } from './app/app.module'; import { SharedModule } from './app/shared/shared.module'; @@ -16,6 +18,10 @@ import { Meta } from './angular2-meta'; // import * as LRU from 'modern-lru'; +export function createTranslateLoader(http: Http) { + return new TranslateStaticLoader(http, './assets/i18n', '.json'); +} + export function getLRU(lru?: any) { // use LRU for node // return lru || new LRU(10); @@ -37,6 +43,11 @@ export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE'; @NgModule({ bootstrap: [AppComponent], imports: [ + TranslateModule.forRoot({ + provide: TranslateLoader, + useFactory: (createTranslateLoader), + deps: [Http] + }), NgbModule.forRoot(), UniversalModule, // BrowserModule, HttpModule, and JsonpModule are included diff --git a/src/node.module.ts b/src/node.module.ts index 10d64aa0b9..1a7ee825c8 100755 --- a/src/node.module.ts +++ b/src/node.module.ts @@ -1,9 +1,11 @@ import { NgModule } from '@angular/core'; +import { Http } from '@angular/http'; import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; import { UniversalModule, isBrowser, isNode } from 'angular2-universal/node'; // for AoT we need to manually split universal packages import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateLoader, TranslateModule, TranslateStaticLoader } from 'ng2-translate'; import { AppModule, AppComponent } from './app/app.module'; import { SharedModule } from './app/shared/shared.module'; @@ -13,6 +15,10 @@ import { CacheService } from './app/shared/cache.service'; // see https://github.com/angular/angular/pull/12322 import { Meta } from './angular2-meta'; +export function createTranslateLoader(http: Http) { + return new TranslateStaticLoader(http, './assets/i18n', '.json'); +} + export function getLRU() { return new Map(); } @@ -29,6 +35,11 @@ export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE'; @NgModule({ bootstrap: [AppComponent], imports: [ + TranslateModule.forRoot({ + provide: TranslateLoader, + useFactory: (createTranslateLoader), + deps: [Http] + }), NgbModule.forRoot(), UniversalModule, // BrowserModule, HttpModule, and JsonpModule are included diff --git a/webpack.config.ts b/webpack.config.ts index d6b7baee1b..9077b7371d 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -14,11 +14,16 @@ export var commonPlugins = [ } ), - // Copy fonts - new CopyWebpackPlugin([{ - from: path.join(__dirname, 'node_modules', 'font-awesome', 'fonts'), - to: path.join('assets', 'fonts') - }]), + // Copy fonts and i18n + new CopyWebpackPlugin([ + { + from: path.join(__dirname, 'node_modules', 'font-awesome', 'fonts'), + to: path.join('assets', 'fonts') + }, { + from: path.join(__dirname, 'resources', 'i18n'), + to: path.join('assets', 'i18n') + } + ]), // Loader options new webpack.LoaderOptionsPlugin({