Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

force common module not to use translations from lazy loaded module #24

Closed
mrklika opened this issue Aug 19, 2019 · 15 comments
Closed

force common module not to use translations from lazy loaded module #24

mrklika opened this issue Aug 19, 2019 · 15 comments
Assignees
Labels
enhancement New feature or request

Comments

@mrklika
Copy link

mrklika commented Aug 19, 2019

Hi, when I use lazy loaded translation file in my lazy loaded module +dashboard like

providers: [{ provide: TRANSLOCO_SCOPE, useValue: 'dashboard' }]

Is there any way to force my NOT lazy loaded modules used in +dashboard module to use translations NOT from /18n/dashboard/en.json, but just from /i18n/en.json ?

The problem is that my common module will not always be used just inside the +dashboard lazy loaded module, but inside more modules. So I do not want to create translations in all my modules.


Or maybe have a separate file right inside the common module folder and force the common component to use translations contained in the folder instead of some lazy loaded translation file specified in lazy loaded module above?

my common module
image

.

@NetanelBasal
Copy link
Contributor

Do you mean something like #21 (comment)?

@mrklika
Copy link
Author

mrklika commented Aug 20, 2019

By your suggested solution I tried:

image

CompanyTeamCardTranslationsModule was imported to CompanyTeamCardModule and it still seems like my lazy loaded translation file /i18n/dashboard/cs.json is still used for translations.

image

then, inside the template:

image

which reffered to my lazy loaded translation file /i18n/dashboard/cs.json

image

with result:

image

@shaharkazaz
Copy link
Collaborator

shaharkazaz commented Aug 20, 2019

@mrklika do you still have the scope 'dashboard'? if so, you don't need it anymore since the translations are now on the global lang.

We are releasing a solution for this OOTB hopefully today, stay tuned 👍

@mrklika
Copy link
Author

mrklika commented Aug 20, 2019

@shaharkazaz Yes, I have a lazy loaded module +dashboard in which I specify my lazy loaded translation file like:

providers: [{ provide: TRANSLOCO_SCOPE, useValue: 'dashboard' }]

Inside the +dashboard module I have a COMMON module in which I want to use translations from the file inside the common module, but also from the main en.json / cs.json files:

image

But when I try to translate something inside the teplate, it takes translations from the /18n/dashboard/en.json file not from the company-team-card.translations.ts.

Alright! :)

@NetanelBasal
Copy link
Contributor

NetanelBasal commented Aug 22, 2019

Lazy Load Translation Files

Let's say we have a todos page and we want to create separate translation files for this page and load them only when the user navigates there. First, we need to create a todos folder (or whatever name you choose); In it, we create a translation file for each language we want to support:

├─ i18n/
   ├─ en.json
   ├─ es.json
   ├─ todos/
      ├─ en.json
      ├─ es.json

We have several ways of telling Transloco to use them, via setting the TRANSLOCO_SCOPE provider based on Angular's DI rules.

We can set it the providers list of a lazy module:

const routes: Routes = [
  {
    path: '',
    component: TodosComponent
  }
];

@NgModule({
  declarations: [TodosComponent],
  providers: [{ provide: TRANSLOCO_SCOPE, useValue: 'todos' }],
  imports: [CommonModule, RouterModule.forChild(routes), TranslocoModule]
})
export class TodosModule {}

We can set it in a component's providers:

@Component({
  selector: 'my-comp',
  templateUrl: './my-comp.component.html',
  providers: [
    {
      provide: TRANSLOCO_SCOPE,
      useValue: 'todos'
    }
  ]
})
export class MyComponent {}

Or we can set the scope input in the transloco structural directive:

<ng-container *transloco="let t; scope: 'todos';">
  <h1>{{ t.todos.keyFromTodo }}</h1>
</ng-container>

Each one of these options tells Transloco to load the corresponding scope based on the current language and merge it under the scope namespace into the active language translation object.

For example, if the current language is en, it will load the file todos/en.json and set the response to be the following:

{
  header: '',
  login: '',
  todos: {
    submit: '',
    title: ''
  }
}

So now we can access each one of the todos keys by using the todos namespace:

{{ 'todos.title' | transloco }}

<span transloco="toods.submit"></span>

By default, the namespace will be the scope name (camelCased), but we can override it by using the config.scopeMapping config:

{
  provide: TRANSLOCO_CONFIG,
   useValue: {
    defaultLang: 'en',
    scopeMapping: {
      todos: 'customName'
    }
  }
}

And now we can access it through customName instead of the original scope name (todos in our case):

{{ 'customName.title' | transloco }}

<span transloco="customName.submit"></span>

Note that to use it in the current version (1.x.x), we need to set config.scopeStrategy to shared. In the next major release, it will be the default.

@NetanelBasal
Copy link
Contributor

@mrklika check it out and let me know if this functionality solves your issue.

@moniuch
Copy link

moniuch commented Aug 24, 2019

From my experience: feature modules usually refer to 2 scopes: one would be todos in this example, and the other would be general (or, common) - where all the widely used phrases like "OK", "Cancel", "Are you sure you want to {{action}}?" are stored. Not sure how transloco sees that kind of dependency, but this is how lot of people set up the i18n environment in order to remain DRY. That might pose some migration issues if transloco does not support it.

@NetanelBasal
Copy link
Contributor

one would be todos in this example, and the other would be general

The general is the global scope.

@NetanelBasal
Copy link
Contributor

For example, the global scope will be:

// en.json
{
 OK: '',
 Cancel: ''
}

And todos scope will be:

// todos/en.json
{
 submitAction: '',
 title: ''
}

Then, when you ask to load the todos scope, Transloco will merge them:

{
 OK: '',
 Cancel: ''
 todos: {
  submitAction: '',
  title: ''
 }
}

So, now you can access both:

{{ 'todos.title' | transloco }}

<button transloco="Cancel"></button>

@mrklika
Copy link
Author

mrklika commented Aug 26, 2019

Hi,

after updating to 1.2.0 version and setting mergeStrategy: 'shared' I tried tu use translations in my lazy loaded template from both lazy loaded translation file and general translation file and I see no results,

Could you please check the minimal reproduction of my problem at:

https://stackblitz.com/edit/angular-tmc7wd

In the project, there is implemented Transloco with one lazy loaded module.

image

Thank you! :)

@shaharkazaz
Copy link
Collaborator

shaharkazaz commented Aug 26, 2019

@mrklika The feature is still in a pull request and not released 🙂 #33

@mrklika
Copy link
Author

mrklika commented Aug 26, 2019

@mrklika The feature is still in a pull request and not released 🙂 #33

Ok thanks for response! 🙂

@mrklika
Copy link
Author

mrklika commented Aug 26, 2019

@shaharkazaz Can I please ask you when do you approx. plan to release the feature? Thanks

@shaharkazaz
Copy link
Collaborator

@mrklika It's currently in the stage of testing. I'm sure it will be out this week, can't tell you when but as soon as it's ready.

@NetanelBasal
Copy link
Contributor

@mrklika it's available in v1.3.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants