diff --git a/package.json b/package.json index 89f6eef5ad..9bc80b07ac 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,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", 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.html b/src/app/app.component.html index a7d039d11d..a83351f943 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,9 +1,11 @@ -

DSpace

+

{{ 'title' | translate }}

+

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

+

{{ example }}

diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8951b4881e..39f73ee36b 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,11 +1,42 @@ -import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { Component, ChangeDetectionStrategy, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; + +import { TranslateService } from 'ng2-translate'; @Component({ changeDetection: ChangeDetectionStrategy.Default, encapsulation: ViewEncapsulation.Emulated, selector: 'ds-app', templateUrl: './app.component.html', - styleUrls: [ './app.component.scss' ] + styleUrls: ['./app.component.scss'] }) -export class AppComponent { +export class AppComponent implements OnDestroy, OnInit { + + example: string; + + data: any = { + greeting: 'Hello', + recipient: 'World' + } + + private registerSubscription: any; + + constructor(public translate: TranslateService) { + // 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'); + } + + ngOnInit() { + this.registerSubscription = this.translate.get('example.with.data', { greeting: 'Hello', recipient: 'DSpace' }).subscribe((translation: string) => { + this.example = translation; + }); + } + + ngOnDestroy() { + if (this.registerSubscription) { + this.registerSubscription.unsubscribe(); + } + } + } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 86c72cdbba..0f8b5e5625 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -2,6 +2,9 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule } from '@angular/router'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +import { TranslateModule } from 'ng2-translate/ng2-translate'; + import { ApiService } from './api.service'; import { ModelService } from './model/model.service'; @@ -9,6 +12,7 @@ const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here CommonModule, RouterModule, + TranslateModule, FormsModule, ReactiveFormsModule ]; diff --git a/src/browser.module.ts b/src/browser.module.ts index 512e68958c..e6475cc118 100755 --- a/src/browser.module.ts +++ b/src/browser.module.ts @@ -1,9 +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 { TranslateLoader, TranslateModule, TranslateStaticLoader } from 'ng2-translate'; + import { AppModule, AppComponent } from './app/app.module'; import { SharedModule } from './app/shared/shared.module'; import { CacheService } from './app/shared/cache.service'; @@ -14,6 +17,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); @@ -33,9 +40,14 @@ export function getResponse() { export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE'; @NgModule({ - bootstrap: [ AppComponent ], + bootstrap: [AppComponent], imports: [ - // MaterialModule.forRoot() should be included first + TranslateModule.forRoot({ + provide: TranslateLoader, + useFactory: (createTranslateLoader), + deps: [Http] + }), + UniversalModule, // BrowserModule, HttpModule, and JsonpModule are included FormsModule, diff --git a/src/node.module.ts b/src/node.module.ts index c7a8ad6296..5395e54750 100755 --- a/src/node.module.ts +++ b/src/node.module.ts @@ -1,8 +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 { TranslateLoader, TranslateModule, TranslateStaticLoader } from 'ng2-translate'; + import { AppModule, AppComponent } from './app/app.module'; import { SharedModule } from './app/shared/shared.module'; import { CacheService } from './app/shared/cache.service'; @@ -11,6 +14,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(); } @@ -25,9 +32,14 @@ export function getResponse() { export const UNIVERSAL_KEY = 'UNIVERSAL_CACHE'; @NgModule({ - bootstrap: [ AppComponent ], + bootstrap: [AppComponent], imports: [ - // MaterialModule.forRoot() should be included first + TranslateModule.forRoot({ + provide: TranslateLoader, + useFactory: (createTranslateLoader), + deps: [Http] + }), + UniversalModule, // BrowserModule, HttpModule, and JsonpModule are included FormsModule, @@ -63,9 +75,9 @@ export class MainModule { universalCache[CacheService.KEY] = JSON.stringify(this.cache.dehydrate()); } - /** - * Clear the cache after it's rendered - */ + /** + * Clear the cache after it's rendered + */ universalAfterDehydrate = () => { // comment out if LRU provided at platform level to be shared between each user this.cache.clear(); diff --git a/webpack.config.ts b/webpack.config.ts index a6249585c2..63fae60aa4 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -2,6 +2,7 @@ var webpack = require('webpack'); var path = require('path'); var clone = require('js.clone'); var webpackMerge = require('webpack-merge'); +let CopyWebpackPlugin = require('copy-webpack-plugin'); export var commonPlugins = [ new webpack.ContextReplacementPlugin( @@ -13,6 +14,11 @@ export var commonPlugins = [ } ), + new CopyWebpackPlugin([{ + from: path.join(__dirname, 'resources', 'i18n'), + to: path.join('assets', 'i18n') + }]), + // Loader options new webpack.LoaderOptionsPlugin({ options: {