Skip to content

Commit

Permalink
Added Locale superclass & updated documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
robisim74 committed May 10, 2016
1 parent 6fc903b commit 5ecd8f4
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 161 deletions.
218 changes: 125 additions & 93 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,116 +33,159 @@ To load the package you have two methods:
```

## Getting the translation
Now this library uses pure pipes. To know the advantages over impure pipes, please see [here](https://angular.io/docs/ts/latest/guide/pipes.html).

### Messages
```
expression | translate
expression | translate:lang
```
where `expression` is a string key that indicates the message to translate.
where `expression` is a string key that indicates the message to translate and `lang` is the language code for the `LocalizationService`.

For example, to get the translation, add in the template:
```Html
{{ 'TITLE' | translate }}
{{ 'TITLE' | translate:lang }}
```
and include `TranslatePipe` in the component:
and include in the component:
```TypeScript
import {TranslatePipe} from 'angular2localization/angular2localization';
import {LocalizationService, TranslatePipe} from 'angular2localization/angular2localization';

@Component({
...
pipes: [TranslatePipe]
...
pipes: [TranslatePipe]
})

export class AppComponent {

constructor(public localization: LocalizationService) {
...
}

// Gets the language code for the LocalizationService.
get lang(): string {

return this.localization.languageCode;

}

}
```
With Angular 2 `I18nSelectPipe` that displays the string that matches the current value:
```Html
{{ expression | i18nSelect:mapping | translate }}
{{ expression | i18nSelect:mapping | translate:lang }}
```
With Angular 2 `I18nPluralPipe` that pluralizes the value properly:
```Html
{{ expression | i18nPlural:mapping | translate }}
{{ expression | i18nPlural:mapping | translate:lang }}
```

### Dates
```
expression | localedate[:format]
expression | localedate[:defaultLocale[:format]]
```
where `expression` is a date object or a number (milliseconds since UTC epoch) and `format` indicates which date/time components to include.
where `expression` is a date object or a number (milliseconds since UTC epoch), `defaultLocale` is the default locale and `format` indicates which date/time components to include. See Angular 2 `DatePipe` for further information.

For example, to get the local date, add in the template:
```Html
{{ today | localedate:'fullDate' }}
{{ today | localedate:defaultLocale:'fullDate' }}
```
and include in the component:
```TypeScript
import {LocalizationService, LocaleDatePipe} from 'angular2localization/angular2localization';

@Component({
...
pipes: [LocaleDatePipe]
})

export class AppComponent {

constructor(public locale: LocaleService) {
...
}

// Gets the default locale.
get defaultLocale(): string {

return this.locale.getDefaultLocale();

}

}
```
and include `LocaleDatePipe` in the component. See Angular 2 `DatePipe` for further information.

### Numbers
#### Decimals
```
expression | localedecimal[:digitInfo]
expression | localedecimal[:defaultLocale:[digitInfo]]
```
where `expression` is a number and `digitInfo` has the following format: `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`.
where `expression` is a number, `defaultLocale` is the default locale and `digitInfo` has the following format: `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`. See Angular 2 `DecimalPipe` for further information.

For example, to get the local decimal, add in the template:
```Html
{{ pi | localedecimal:'1.5-5' }}
{{ pi | localedecimal:defaultLocale:'1.5-5' }}
```
and include `LocaleDecimalPipe` in the component. See Angular 2 `DecimalPipe` for further information.
and include `LocaleDecimalPipe` and `get defaultLocale()` in the component.
#### Percentages
```
expression | localepercent[:digitInfo]
expression | localepercent[:defaultLocale:[digitInfo]]
```

For example, to get the local percentage, add in the template:
```Html
{{ a | localepercent:'1.1-1' }}
{{ a | localepercent:defaultLocale:'1.1-1' }}
```
and include `LocalePercentPipe` in the component.
and include `LocalePercentPipe` and `get defaultLocale()` in the component.
#### Currencies
```
expression | localecurrency[:symbolDisplay[:digitInfo]]]
expression | localecurrency[:defaultLocale[:currency[:symbolDisplay[:digitInfo]]]]
```
where `symbolDisplay` is a boolean indicating whether to use the currency symbol (e.g. $) or the currency code (e.g. USD) in the output.
where `currency` is the current currency and `symbolDisplay` is a boolean indicating whether to use the currency symbol (e.g. $) or the currency code (e.g. USD) in the output.

For example, to get the local currency, add in the template:
```Html
{{ b | localecurrency:true:'1.2-2' }}
```
and include `LocaleCurrencyPipe` in the component.
#### List
Now you can localize an array of objects or an array of arrays:
{{ b | localecurrency:defaultLocale:currency:true:'1.2-2' }}
```
*ngFor="let item of items | translatearray: {'keyname': {'pipe': '', 'format': '', 'symbolDisplay': bool, 'digitInfo': ''}
and include `LocaleCurrencyPipe`, `get defaultLocale()` and `get currency()` in the component:
```TypeScript
// Gets the current currency.
get currency(): string {

return this.locale.getCurrentCurrency();

}
```
where the parameters of `translatearray` are in Json format.

For example, to get the localized array, add in the template:
### List
Now you can localize a list simply. For example:
```Html
<!--Array of Data objects-->
<md-card *ngFor="let item of DATA | translatearray: {'name': '',
'position': {
'pipe': 'translate'
},
'salary': {
'pipe': 'localecurrency',
'symbolDisplay': true,
'digitInfo': '1.0-0'
},
'startDate': {
'pipe': 'localedate',
'format': 'mediumDate'
}
}">
<md-card *ngFor="let item of DATA">
<md-card-title>{{ item.name }}</md-card-title>
<md-card-content>
<md-list>
<md-list-item>
<h3 md-line>{{ item.position }}</h3>
<p md-line>{{ item.salary }}</p>
<p md-line>{{ item.startDate }}</p>
<h3 md-line>{{ item.position | translate:lang }}</h3>
<p md-line>{{ item.salary | localecurrency:defaultLocale:currency:true:'1.0-0' }}</p>
<p md-line>{{ item.startDate | localedate:defaultLocale:'mediumDate' }}</p>
</md-list-item>
</md-list>
</md-card-content>
</md-card>
```
and include `TranslateArrayPipe` in the component.

### Advanced use
If you want, you can avoid including `get lang()`, `get defaultLocale()` or `get currency()` by extending the `Locale` superclass in components:
```TypeScript
import {Locale, LocaleService, LocalizationService} from 'angular2localization/angular2localization';
...
export class AppComponent extends Locale {

constructor(public locale: LocaleService, public localization: LocalizationService) {
super(locale, localization);
...
}

}
```

## First scenario
> You need to localize dates and numbers, but no messages.
Expand All @@ -152,60 +195,60 @@ Add in the route component in order to access the data of location from anywhere
import {LocaleService} from 'angular2localization/angular2localization';

@Component({
selector: 'app-component',
...
providers: [LocaleService], // Inherited by all descendants.
selector: 'app-component',
...
providers: [LocaleService], // Inherited by all descendants.
})

export class AppComponent {

constructor(public locale: LocaleService,) {
constructor(public locale: LocaleService,) {

// Required: default language (ISO 639 two-letter code) and country (ISO 3166 two-letter, uppercase code).
this.locale.definePreferredLocale('en', 'US');
// Required: default language (ISO 639 two-letter code) and country (ISO 3166 two-letter, uppercase code).
this.locale.definePreferredLocale('en', 'US');

// Optional: default currency (ISO 4217 three-letter code).
this.locale.definePreferredCurrency('USD');
// Optional: default currency (ISO 4217 three-letter code).
this.locale.definePreferredCurrency('USD');

}
}

}
```

## Second scenario
> You only need to translate messages.
### Basic usage
Add in the route component in order to access the data of location from anywhere in the application:
```TypeScript
import {LocaleService, LocalizationService} from 'angular2localization/angular2localization';

@Component({
selector: 'app-component',
...
providers: [LocaleService, LocalizationService], // Inherited by all descendants.
selector: 'app-component',
...
providers: [LocaleService, LocalizationService], // Inherited by all descendants.
})

export class AppComponent {

constructor(public locale: LocaleService, public localization: LocalizationService) {
constructor(public locale: LocaleService, public localization: LocalizationService) {

// Adds a new language (ISO 639 two-letter code).
this.locale.addLanguage('en');
// Add a new language here.
// Adds a new language (ISO 639 two-letter code).
this.locale.addLanguage('en');
// Add a new language here.

// Required: default language and expiry (No days). If the expiry is omitted, the cookie becomes a session cookie.
this.locale.definePreferredLanguage('en', 30);
// Required: default language and expiry (No days). If the expiry is omitted, the cookie becomes a session cookie.
this.locale.definePreferredLanguage('en', 30);

}
}

}
```
Also add in the main:
```TypeScript
bootstrap(AppComponent, [HTTP_PROVIDERS]);
```
#### Direct loading

### Direct loading
To initialize `LocalizationService` for the direct loading, add the following code in the body of constructor of the route component:
```TypeScript
var translationEN = {
Expand All @@ -218,12 +261,15 @@ var translationEN = {
// Required: adds a new translation with the given language code.
this.localization.addTranslation('en', translationEN);
// Add a new translation with the given language code here.
this.localization.updateTranslation(); // Need to update the translation.
```
#### Asynchronous loading

### Asynchronous loading
Alternatively, to initialize `LocalizationService` for the asynchronous loading add the following code in the body of constructor of the route component:
```TypeScript
// Required: initializes the translation provider with the given path prefix.
this.localization.translationProvider('./resources/locale-');
this.localization.updateTranslation(); // Need to update the translation.
```
and create the `json` files of the translations such as `locale-en.json`:
```
Expand All @@ -234,7 +280,8 @@ and create the `json` files of the translations such as `locale-en.json`:
}
```
N.B. Resource files must be saved in `UTF-8` format.
#### Special characters

### Special characters
You can use quotes inside a string, as long as they don't match the quotes surrounding the string:
```
"It wasn't a dream."
Expand All @@ -244,35 +291,17 @@ Because strings must be written within quotes, use the `\` escape character to i
"\"What's happened to me?\" he thought."
```

### Advanced use with Router
If you use a `Router` in an extended application, you can create an instance of `LocalizationService` for every asynchronously loaded component.
Each instance is different, and can be directly or asynchronously loaded, as in this example:
```TypeScript
export class I18nComponent {

// Instantiates a new LocalizationService for this component and for its descendants.
constructor(public localizationI18n: LocalizationService) {

// Required: initializes the translation provider with the given path prefix.
this.localizationI18n.translationProvider('./resources/locale-i18n-');

}

}
```
In this way, application performance and memory usage are optimized.

### Changing language
To change language at runtime, call the following method:
```TypeScript
this.locale.setCurrentLanguage(language);
this.localization.updateTranslation(); // Need to update the translation.
```
where `language` is the two-letter code of the new language (ISO 639).

## Third scenario
> You need to translate messages, dates and numbers.
### Basic usage
Unlike what said for messages, use the following code in the body of constructor of the route component:
```TypeScript
// Adds a new language (ISO 639 two-letter code).
Expand All @@ -285,10 +314,12 @@ this.locale.definePreferredLocale('en', 'US', 30);
// Optional: default currency (ISO 4217 three-letter code).
this.locale.definePreferredCurrency('USD');
```

### Changing locale and currency
To change locale at runtime, call the following method:
```TypeScript
this.locale.setCurrentLocale(language, country);
this.localization.updateTranslation(); // Need to update the translation.
```
where `language` is the two-letter code of the new language (ISO 639) and `country` is the two-letter, uppercase code of the new country (ISO 3166).

Expand All @@ -298,8 +329,6 @@ this.locale.setCurrentCurrency(currency);
```
where `currency` is the three-letter code of the new currency (ISO 4217).

See the [demo](http://robisim74.github.io/angular2localization) for a sample code.

## Internationalization API
To localize dates and numbers, this library uses `Intl` API, through Angular 2.
All modern browsers, except Safari, have implemented this API. You can use [Intl.js](https://github.com/andyearnshaw/Intl.js) to extend support to all browsers.
Expand All @@ -309,5 +338,8 @@ Just add one script tag in your `index.html`:
```
When specifying the `features`, you have to specify what locale, or locales to load.

## Boilerplates
[Angular 2 Localization with an ASP.NET CORE MVC Service](https://damienbod.com/2016/04/29/angular-2-localization-with-an-asp-net-core-mvc-service/) @damienbod

##License
MIT
1 change: 1 addition & 0 deletions angular2localization.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Exports services & pipes.
export * from './src/services/localization.service';
export * from './src/services/locale.service';
export * from './src/services/locale';
export * from './src/services/locale-number';
export * from './src/pipes/translate.pipe';
export * from './src/pipes/locale-date.pipe';
Expand Down
Loading

0 comments on commit 5ecd8f4

Please sign in to comment.