Hi,
I'm using this theme in my Angluar Projekt.
I need to translate the title of the menuItems depending on the current language of my application.
Is there a possibility to do this?
I'm use ngx-translate for translation in my project.
Hi @SebastianFreund, take a look at https://github.com/akveo/ngx-admin/issues/1305. Hopefully, this helps.
Hi @nnixaa!
Yes, it helps me but it didn't solve the whole problem.
I have implemented the descripted solution, but if the language changes, the menuItems will not be translated again.
Any ideas how I can solve this problem?
@SebastianFreund did you look at the NBMenuInternalService? There is a reset items. not sure if this will help but maybe after a translate, reset the menu? I agree we should be able to pass a pipe into nebular components to make it easier for the switch to be more native, then having to call a function.... Maybe a feature improvement can be made @nnixaa
@blankstar85 Thank you for your help! I haven't seen the NbMenuInternalService before, but your solution works for me. But I agree with you, to pass a pipe into the components would it make much easier!
The only problem I still have: After reseting the menu, no menuItem is selected and I don't know how to select the menuItem which was selected before the reset. I have tried itemSelect() from NbMenuInternalService, but this didn't work.
I decided to go a different way than the solution proposed in https://github.com/akveo/ngx-admin/issues/1305
In my pages.component.ts, I iterate on every menu item and change only the title of each element.
I also subscribed to the onLangChange event and simply re-translate the titles from there. No need to ever reset the menu items.
I created a gist for this. Please feel free to leave me comments.
Great solution @dizco !
My problem was, that i writed the translation-string in the title field. In this way i had to clone the MENU_ITEMS object, that i don't overwrite the translation-string when i translate the title. -> Through the clone I lost the object-reference on retranslate an so i need to reset the menu.
Now i store the translation-string in the data field (like @dizco in the key field) and now there is no need to reset the menu. Every thing works fine.
This is my code from pages.component.ts:
menu: NbMenuItem[];
constructor( private translateService: TranslateService ) { }
ngOnInit()
{
this.menu = MENU_ITEMS;
this.translateService.onLangChange.subscribe( event => this.translateMenuItems() );
this.translateMenuItems();
}
translateMenuItems()
{
this.menu.forEach( item => this.translateMenuItem( item ) );
}
translateMenuItem( menuItem: NbMenuItem )
{
if ( menuItem.children != null )
{
menuItem.children.forEach( item => this.translateMenuItem( item ) );
}
menuItem.title = this.translateService.instant( menuItem.data );
}
@SebastianFreund ah yes I faced that issue too, seems like we have some very similar solutions :)
@SebastianFreund on your solution the translation works only once because the title is translated and no translation key is available
one option is to copy the object?
menu: NbMenuItem[];
save_menu: NbMenuItem[];
constructor( private translate: TranslateService ) {
this.menu = MENU_ITEMS;
this.save_menu = JSON.parse(JSON.stringify(MENU_ITEMS))
}
ngOnInit() {
this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
this.menu = this.save_menu;
this.save_menu = JSON.parse(JSON.stringify(this.save_menu));
this.translateMenuItems();
});
this.translateMenuItems();
}
translateMenuItems() {
this.menu.forEach( item => {
this.translateMenuItem( item );
});
}
translateMenuItem( menuItem: NbMenuItem ) {
if ( menuItem.children != null ) {
menuItem.children.forEach( item => this.translateMenuItem( item ) );
}
menuItem.title = this.translate.instant( menuItem.title );
}
}
This was my first solution. But you have to reset the menu with this solution, and then you lose the selection of the current selected page. Now i store the translation key in the data-field of the menu-item. Then there is no need to copy the object.
thanks for your reply and idea. works!
export class PagesComponent implements OnInit {
menu: NbMenuItem[];
constructor( private translate: TranslateService ) {
this.menu = MENU_ITEMS;
}
ngOnInit() {
this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
this.translateMenuItems();
});
this.translateMenuItems();
}
translateMenuItems() {
this.menu.forEach( item => {
this.translateMenuItem( item );
});
}
translateMenuItem( menuItem: NbMenuItem ) {
if ( menuItem.children != null ) {
menuItem.children.forEach( item => this.translateMenuItem( item ) );
}
if(menuItem.data === undefined) {
menuItem.data = menuItem.title;
menuItem.title = this.translate.instant( menuItem.title );
} else {
menuItem.title = this.translate.instant( menuItem.data );
}
}
}
My working example:
export class SidebarComponent implements OnInit {
menu: NbMenuItem[];
constructor( private translate: TranslateService ) {}
ngOnInit() {
this.menu = MENU_ITEMS;
this.translate.onLangChange.subscribe((event: LangChangeEvent) => {
this.translateMenuItems();
});
this.translateMenuItems();
}
translateMenuItems() {
this.menu.forEach((item: NbMenuItem) => {
this.translateMenuItem(item);
});
}
translateMenuItem( menuItem: NbMenuItem ) {
if ( menuItem.children != null ) {
menuItem.children.forEach((item: NbMenuItem) => this.translateMenuItem(item) );
}
if (menuItem.data === undefined) {
menuItem.data = menuItem.title;
this.getTranslation(menuItem, menuItem.title);
} else {
this.getTranslation(menuItem, menuItem.data);
}
}
getTranslation(item: NbMenuItem, key: string) {
const k = `sidebar.${key.toLowerCase()}`;
this.translate.get(k).subscribe((translation: string) => {
item.title = translation;
});
}
}
Most helpful comment
thanks for your reply and idea. works!