Skip to content

Commit 1b79bc3

Browse files
sinediedsnowyu
andcommitted
feat: add i18n module and language selection at generation (close #262)
- Add i18n module - Add dedicated language selector component - Allow language selection during project generator - Fix some Ionic template issues Credits for original idea and work goes to @snowyu BREAKING CHANGES: Move all i18n related components to dedicated module Co-authored-by: snowyu <[email protected]>
1 parent 3005d5d commit 1b79bc3

File tree

53 files changed

+541
-258
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+541
-258
lines changed

generators/app/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const asciiLogo = require('@ngx-rocket/ascii-logo');
99
const pkg = require('../../package.json');
1010
const prompts = require('./prompts');
1111
const options = require('./options');
12+
const getLanguages = require('./languages');
1213

1314
const packageJsonFile = 'package.json';
1415

@@ -132,10 +133,16 @@ class NgxGenerator extends Generator {
132133
this.props.desktop = this.props.desktop || [];
133134
this.props.utility = this.props.utility || [];
134135
this.props.tools = this.props.tools || [];
136+
this.props.languages = this.props.languages || ['en-US', 'fr-FR'];
135137
this.shareProps(this.props);
136138
}
137139

138140
configuring() {
141+
// Add prefix rules for languages
142+
getLanguages().forEach(language => {
143+
this._prefixRules[language] = (props => props.languages.includes(language));
144+
});
145+
139146
this.insight.track(
140147
'generator',
141148
this.props.target,

generators/app/languages.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const path = require('path');
2+
const globby = require('globby');
3+
4+
// Extract languages from files available in /templates/src/translations/
5+
module.exports = function getLanguages() {
6+
const files = globby.sync(path.join(__dirname, 'templates/src/translations/*.json'));
7+
return files.map(file => path.basename(file).substring(2, 7));
8+
};

generators/app/prompts.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
const getLanguages = require('./languages');
2+
13
module.exports = [
24
{
35
type: 'input',
@@ -136,6 +138,14 @@ module.exports = [
136138
message: 'Do you want analytics support (with Angulartics2)?',
137139
default: false
138140
},
141+
{
142+
type: 'checkbox',
143+
name: 'languages',
144+
message: 'Which languages do you want to support?',
145+
choices: () => getLanguages()
146+
.map(language => ({ value: language, name: language, checked: language === 'en-US' })),
147+
validate: value => value.length > 0 ? true : 'You must pick at least one language.'
148+
},
139149
{
140150
type: 'list',
141151
name: 'analyticsProvider',

generators/app/templates/.htmlhintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"attr-value-double-quotes": true,
55
"tag-pair": true,
66
"spec-char-escape": true,
7-
"id-unique": true,
7+
"id-unique": false,
88
"src-not-empty": true,
99
"attr-no-duplication": true,
1010
"title-require": true,

generators/app/templates/src/app/_app.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
2525
<% } -%>
2626

2727
import { environment } from '@env/environment';
28-
import { Logger, I18nService, untilDestroyed } from '@app/core';
28+
import { Logger, untilDestroyed } from '@app/core';
29+
import { I18nService } from '@app/i18n';
2930

3031
<% if (props.target.includes('cordova')) { -%>
3132

generators/app/templates/src/app/about/_about-routing.module.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NgModule } from '@angular/core';
22
import { Routes, RouterModule } from '@angular/router';
33

4-
import { extract } from '@app/core';
4+
import { extract } from '@app/i18n';
55
<% if (!props.lazy) { -%>
66
import { Shell } from '@app/shell/shell.service';
77
<% } -%>

generators/app/templates/src/app/auth/__auth+bootstrap.login.component.html

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,8 @@
33
<h1 translate>APP_NAME</h1>
44
<div>
55
<h6 class="d-inline-block">v{{version}}</h6>
6-
<div class="d-inline-block ml-3" ngbDropdown>
7-
<button id="language-dropdown" class="btn btn-sm btn-secondary" ngbDropdownToggle>
8-
{{currentLanguage}}
9-
</button>
10-
<div ngbDropdownMenu aria-labelledby="language-dropdown">
11-
<button class="dropdown-item" *ngFor="let language of languages" (click)="setLanguage(language)">
12-
{{language}}
13-
</button>
14-
</div>
6+
<div class="d-inline-block ml-3">
7+
<app-language-selector></app-language-selector>
158
</div>
169
</div>
1710
<div class="container">

generators/app/templates/src/app/auth/__auth+ionic.login.component.html

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,8 @@
77
<h1 translate>APP_NAME</h1>
88
<h6>v{{version}}</h6>
99
<ion-list *ngIf="isWeb" color="primary" lines="none" class="ion-no-padding">
10-
<ion-item lines="none" color="primary">
11-
<ion-label><span translate>Language</span></ion-label>
12-
<ion-select [ngModel]="currentLanguage" (ngModelChange)="setLanguage($event)" interface="popover">
13-
<ion-select-option *ngFor="let language of languages" [value]="language">{{language}}</ion-select-option>
14-
</ion-select>
15-
</ion-item>
10+
<app-language-selector type="select" itemClass="ion-color ion-color-primary item-lines-none">
11+
</app-language-selector>
1612
</ion-list>
1713
</div>
1814
<div class="login-container">

generators/app/templates/src/app/auth/__auth+material.login.component.html

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,7 @@
33
<h1 fxLayoutAlign="center" translate>APP_NAME</h1>
44
<div fxLayout="row" fxLayoutAlign="center center" fxLayoutGap="2rem">
55
<h4 class="version">v{{version}}</h4>
6-
<div class="language-selector">
7-
<button mat-raised-button color="primary" [matMenuTriggerFor]="languageMenu">
8-
{{currentLanguage}}
9-
</button>
10-
<mat-menu #languageMenu="matMenu">
11-
<button mat-menu-item *ngFor="let language of languages" (click)="setLanguage(language)">
12-
{{language}}
13-
</button>
14-
</mat-menu>
15-
</div>
6+
<app-language-selector></app-language-selector>
167
</div>
178
</div>
189
<div class="login-container" fxLayout="row" fxLayoutAlign="center">

generators/app/templates/src/app/auth/__auth+raw.login.component.html

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@
33
<h1 translate>APP_NAME</h1>
44
<div>
55
<strong>v{{version}}</strong>
6-
<select (change)="setLanguage($event.target.value)">
7-
<option *ngFor="let language of languages" [value]="language" [selected]="language === currentLanguage">
8-
{{language}}
9-
</option>
10-
</select>
6+
<app-language-selector></app-language-selector>
117
</div>
128
<div class="container">
139
<form (ngSubmit)="login()" [formGroup]="loginForm" novalidate>

0 commit comments

Comments
 (0)