Skip to content

Commit 0e58324

Browse files
author
Netanel Basal
committed
feat: 🎸 mutli-langs
add support for static lang
2 parents 7ad765a + 8d91b61 commit 0e58324

File tree

10 files changed

+150
-25
lines changed

10 files changed

+150
-25
lines changed

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,8 @@ Alternatively, here is how to use it directly in the template:
431431
</ng-container>
432432
```
433433

434+
Note that it will be used as the **initial language**. If you need it to be **static**, you can use the `static` pipe: `en|static`.
435+
434436
## Custom Loading Template
435437

436438
Transloco provides you with a way to define a loading template, that will be used while the translation file is loading.
@@ -672,9 +674,10 @@ Transloco provides a schematics [command](https://github.com/ngneat/transloco/bl
672674
673675
## Plugins
674676
675-
- [Messageformat](https://github.com/ngneat/transloco/tree/master/projects/ngneat/transloco-messageformat) (offical)
676-
- [Persist Language](https://github.com/ngneat/transloco/tree/master/projects/ngneat/transloco-persist-lang) (offical)
677-
- [Persist Translations](https://github.com/ngneat/transloco/tree/master/projects/ngneat/transloco-persist-translations) (offical)
677+
- [Messageformat](https://github.com/ngneat/transloco/tree/master/projects/ngneat/transloco-messageformat) (official)
678+
- [Persist Language](https://github.com/ngneat/transloco/tree/master/projects/ngneat/transloco-persist-lang) (official)
679+
- [Persist Translations](https://github.com/ngneat/transloco/tree/master/projects/ngneat/transloco-persist-translations) (official)
680+
- [Preload Languages](https://github.com/ngneat/transloco/tree/master/projects/ngneat/transloco-preload-langs) (official)
678681
679682
## Support
680683

projects/ngneat/transloco-preload-langs/tsconfig.lib.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{
2-
"extends": "../../../tsconfig.json",
32
"compilerOptions": {
43
"outDir": "../../../out-tsc/lib",
54
"target": "es2015",

projects/ngneat/transloco/src/lib/helpers.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ export function isBrowser() {
123123
/**
124124
* @example
125125
*
126-
* getPipeValue('todos|scoped', 'scoped') [true, todos]
127-
* getPipeValue('eng|static', 'static') [true, eng]
128-
* getPipeValue('eng', 'static') [false, '']
126+
* getPipeValue('todos|scoped', 'scoped') [true, 'todos']
127+
* getPipeValue('en|static', 'static') [true, 'en']
128+
* getPipeValue('en', 'static') [false, 'en']
129129
*/
130-
export function getPipeValue(str: string, value: string, char = '|') {
130+
export function getPipeValue(str: string, value: string, char = '|'): [boolean, string] {
131131
if (isString(str)) {
132132
const splitted = str.split(char);
133133
const lastItem = splitted.pop();
134-
return lastItem === value ? [true, splitted.toString()] : [false, ''];
134+
return lastItem === value ? [true, splitted.toString()] : [false, lastItem];
135135
}
136136

137137
return [false, ''];
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { TranslocoService } from './transloco.service';
2+
import { getPipeValue } from './helpers';
3+
4+
export function shouldListenToLangChanges(service: TranslocoService, lang: string) {
5+
const [hasStatic] = getPipeValue(lang, 'static');
6+
if (hasStatic === false) {
7+
// If we didn't get 'lang|static' check if it's set in the global level
8+
return service.config.listenToLangChange;
9+
}
10+
11+
// We have 'lang|static' so don't listen to lang changes
12+
return false;
13+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { getPipeValue } from '../helpers';
2+
3+
describe('getPipeValue', () => {
4+
it('should work', () => {
5+
expect(getPipeValue(null, 'static')).toEqual([false, '']);
6+
expect(getPipeValue('en', 'static')).toEqual([false, 'en']);
7+
expect(getPipeValue('en|static', 'static')).toEqual([true, 'en']);
8+
expect(getPipeValue('todos-page|static', 'static')).toEqual([true, 'todos-page']);
9+
});
10+
});

projects/ngneat/transloco/src/lib/tests/transloco.directive.spec.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,95 @@ describe('TranslocoDirective', () => {
202202
}));
203203
});
204204

205+
describe('Multi Langs', () => {
206+
it('should support multi langs', fakeAsync(() => {
207+
host = createHost(
208+
`
209+
<section *transloco="let t;">
210+
<h1>{{ t.home }}</h1>
211+
</section>
212+
<section *transloco="let t; lang: 'es'">
213+
<h2>{{ t.home }}</h2>
214+
</section>
215+
`,
216+
false
217+
);
218+
const service = host.get<TranslocoService>(TranslocoService);
219+
setlistenToLangChange(service);
220+
host.detectChanges();
221+
runLoader();
222+
host.detectChanges();
223+
expect(host.queryHost('h1')).toHaveText('home english');
224+
expect(host.queryHost('h2')).toHaveText('home spanish');
225+
service.setActiveLang('es');
226+
runLoader();
227+
host.detectChanges();
228+
// it should change both because when we don't have static it's
229+
// only the initial value
230+
expect(host.queryHost('h1')).toHaveText('home spanish');
231+
expect(host.queryHost('h2')).toHaveText('home spanish');
232+
}));
233+
234+
it('should respect scopes', fakeAsync(() => {
235+
host = createHost(
236+
`
237+
<section *transloco="let t;">
238+
<h1>{{ t.home }}</h1>
239+
</section>
240+
<section *transloco="let t; lang: 'es'; scope: 'lazy-page'">
241+
<h2>{{ t.lazyPage.title }}</h2>
242+
</section>
243+
`,
244+
false
245+
);
246+
const service = host.get<TranslocoService>(TranslocoService);
247+
setlistenToLangChange(service);
248+
host.detectChanges();
249+
runLoader();
250+
host.detectChanges();
251+
expect(host.queryHost('h1')).toHaveText('home english');
252+
expect(host.queryHost('h2')).toHaveText('Admin Lazy spanish');
253+
service.setActiveLang('es');
254+
runLoader();
255+
host.detectChanges();
256+
// it should change both because when we don't have static it's
257+
// only the initial value
258+
expect(host.queryHost('h1')).toHaveText('home spanish');
259+
expect(host.queryHost('h2')).toHaveText('Admin Lazy spanish');
260+
service.setActiveLang('en');
261+
runLoader();
262+
host.detectChanges();
263+
expect(host.queryHost('h1')).toHaveText('home english');
264+
expect(host.queryHost('h2')).toHaveText('Admin Lazy english');
265+
}));
266+
267+
it('should not change the static lang', fakeAsync(() => {
268+
host = createHost(
269+
`
270+
<section *transloco="let t;">
271+
<h1>{{ t.home }}</h1>
272+
<section *transloco="let inline; lang: 'en|static'">
273+
<h2>{{ inline.home }}</h2>
274+
</section>
275+
</section>
276+
`,
277+
false
278+
);
279+
const service = host.get<TranslocoService>(TranslocoService);
280+
setlistenToLangChange(service);
281+
host.detectChanges();
282+
runLoader();
283+
host.detectChanges();
284+
expect(host.queryHost('h1')).toHaveText('home english');
285+
expect(host.queryHost('h2')).toHaveText('home english');
286+
service.setActiveLang('es');
287+
runLoader();
288+
host.detectChanges();
289+
expect(host.queryHost('h1')).toHaveText('home spanish');
290+
expect(host.queryHost('h2')).toHaveText('home english');
291+
}));
292+
});
293+
205294
describe('Loading Template', () => {
206295
it('should attach and detach view with inline loader template', fakeAsync(() => {
207296
spyOn<TemplateHandler>(TemplateHandler.prototype, 'attachView').and.callThrough();

projects/ngneat/transloco/src/lib/transloco.directive.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import { TRANSLOCO_LOADING_TEMPLATE } from './transloco-loading-template';
2121
import { TRANSLOCO_SCOPE } from './transloco-scope';
2222
import { TranslocoService } from './transloco.service';
2323
import { HashMap, Translation } from './types';
24-
import { getValue } from './helpers';
24+
import { getValue, getPipeValue } from './helpers';
25+
import { shouldListenToLangChanges } from './shared';
2526

2627
@Directive({
2728
selector: '[transloco]'
@@ -60,12 +61,12 @@ export class TranslocoDirective implements OnInit, OnDestroy, OnChanges {
6061
this.loaderTplHandler.attachView();
6162
}
6263

63-
const { listenToLangChange } = this.translocoService.config;
64+
const listenToLangChange = shouldListenToLangChanges(this.translocoService, this.providerLang || this.inlineLang);
6465

6566
this.subscription = this.translocoService.langChanges$
6667
.pipe(
67-
switchMap(globalLang => {
68-
const lang = this.getLang(globalLang);
68+
switchMap(() => {
69+
const lang = this.getLang();
6970
const scope = this.getScope();
7071
this.langName = scope ? `${scope}/${lang}` : lang;
7172
return this.translocoService._loadDependencies(this.langName);
@@ -79,9 +80,7 @@ export class TranslocoDirective implements OnInit, OnDestroy, OnChanges {
7980
let targetLang = this.langName;
8081
const scope = this.getScope();
8182
if (scope) {
82-
targetLang = this.translocoService.isSharedScope
83-
? this.getLang(this.translocoService.getActiveLang())
84-
: this.langName;
83+
targetLang = this.translocoService.isSharedScope ? this.getLang() : this.langName;
8584
}
8685
const translation = this.translocoService.getTranslation(targetLang);
8786
this.langName = targetLang;
@@ -125,24 +124,26 @@ export class TranslocoDirective implements OnInit, OnDestroy, OnChanges {
125124
}
126125

127126
// inline => providers => global
128-
private getLang(globalLang: string) {
127+
private getLang() {
129128
/**
130129
* When the user changes the lang we need to update
131130
* the view. Otherwise, the lang will remain the inline/provided lang
132131
*/
133132
if (this.initialized) {
134-
return globalLang;
133+
return this.translocoService.getActiveLang();
135134
}
136135

137136
if (this.inlineLang) {
138-
return this.inlineLang;
137+
const [_, lang] = getPipeValue(this.inlineLang, 'static');
138+
return lang;
139139
}
140140

141141
if (this.providerLang) {
142-
return this.providerLang;
142+
const [_, lang] = getPipeValue(this.providerLang, 'static');
143+
return lang;
143144
}
144145

145-
return globalLang;
146+
return this.translocoService.getActiveLang();
146147
}
147148

148149
ngOnDestroy() {

projects/ngneat/transloco/src/lib/transloco.pipe.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Subscription } from 'rxjs';
66
import { TRANSLOCO_SCOPE } from './transloco-scope';
77
import { TRANSLOCO_LANG } from './transloco-lang';
88
import { getLangFromScope, getScopeFromLang } from './helpers';
9+
import { shouldListenToLangChanges } from './shared';
910

1011
@Pipe({
1112
name: 'transloco',
@@ -25,8 +26,7 @@ export class TranslocoPipe implements PipeTransform, OnDestroy {
2526
@Optional() @Inject(TRANSLOCO_LANG) private providerLang: string | null,
2627
private cdr: ChangeDetectorRef
2728
) {
28-
const { listenToLangChange } = this.translocoService.config;
29-
this.listenToLangChange = listenToLangChange;
29+
this.listenToLangChange = shouldListenToLangChanges(this.translocoService, this.providerLang);
3030
}
3131

3232
transform(key: string, params: HashMap = {}): string {

src/app/app.module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import { MessageFormatTranspiler } from '@ngneat/transloco-messageformat';
2323
BrowserModule,
2424
AppRoutingModule,
2525
TranslocoModule,
26-
HttpClientModule,
27-
TranslocoPreloadLangsModule.preload(['es', 'todos-page|scoped'])
26+
HttpClientModule
27+
// TranslocoPreloadLangsModule.preload(['es', 'todos-page|scoped'])
2828
// TranslocoPersistLangModule.init({
2929
// getLangFn,
3030
// storage: {

src/app/multilangs/multilangs.component.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,14 @@ <h4>Spanish: (inline lang, scope: lazy-page)</h4>
1010

1111
<provider-lang></provider-lang>
1212

13+
<h4>Static Lang: <code>es</code></h4>
14+
<ng-container *transloco="let t; lang: 'es|static'; loadingTpl: loading">
15+
<p>{{ t.home }}</p>
16+
</ng-container>
17+
18+
<h4>Static Lang with scope <code>lazy-page/es</code></h4>
19+
<ng-container *transloco="let t; lang: 'es|static'; loadingTpl: loading; scope: 'lazy-page'">
20+
<p>{{ t.lazyPage.title }}</p>
21+
</ng-container>
22+
1323
<ng-template #loading>Loading..</ng-template>

0 commit comments

Comments
 (0)