Translations based on specific keys in custom JSON

2019-08-18 18:32发布

问题:

I have a working implementation of the ngx-translate library for Angular, based on several .json files (for example, stored in assets/i18n/en.json).

I want to achieve the following:

There is always a default JSON (for example de.json) and additionally always specific JSON files (for example de_specific.json) that only contain specific translations using the same keys as the respective default JSON. If there is e.g. a translation in the default de.json with "Home": "Startseite", then the translation in the specific de_specific.json is defined as: "Home": "Startseite-Specific". Only the keys, that should be translated specifically, are transferred to the specific JSON files.

Then it should be additionally checked which business case is currently selected and if there is a specific JSON file for that case and if the properties differ from the properties set in the default JSON file. If so, then this specific JSON file should be taken, otherwise the default one.

I have to implement my own Angular-Pipe or Directive for that, which extends the built in pipe of the ngx-translate library. However, I have no idea how and where to do this.

Unfortunately, I have not yet written my own angular pipe or directive and therefore I am pleased about detailed help.

In this service the current (wrong) logic is implemented:

import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import 'moment/locale/de';
import { UserAuthService } from 'app/auth/user-auth.service';

@Injectable()
export class ConfigurationService{

  languages = {
    en: 'English',
    de: 'German',
    de_specific: 'German',
    es: 'Spanish',
    ja: 'Japanese',
    pt: 'Portuguese'
  };

  defaultLanguage = 'en';

  constructor(
    private translate: TranslateService,
    private authService: UserAuthService
  ) {}

  getAutoConfiguredLanguage() {
    const browserLang = this.translate.getBrowserLang();
    const businessCase = this.authService.activeBusinessCase;

    console.log('Browser language: ', browserLang);
    console.log('Current business case: ', businessCase);
    if (this.languages.hasOwnProperty(browserLang)) {
      return businessCase === 'XYZCase' ? browserLang.concat('_specific') :
      browserLang;
    } else {
      return this.defaultLanguage;
    }
  }

}

In the AppComponent the initialization is done within the method initLanguage:

  import { Component, HostListener } from '@angular/core';
  import { UserAuthService } from './auth/user-auth.service';
  import { SettingsService } from './auth/settings.service';
  import { TranslateService } from '@ngx-translate/core';
  import { ConfigurationService } from './config/configuration.service';
  import * as moment from 'moment';
  import { Title } from '@angular/platform-browser';
  import { environment } from '../environments/environment';

  @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
  })
  export class AppComponent {

    constructor(private translate: TranslateService,
                private config: ConfigurationService,
                private settings: SettingsService,
                private authService: UserAuthService,
                private titleService: Title) {
      translate.addLangs(Object.keys(config.languages));
      translate.setDefaultLang(config.defaultLanguage);
      this.initLanguage();
      this.initTabName();
    }

    @HostListener('window:focus')
    onFocus() {
      this.authService.checkAutoLogout();
    }

    initLanguage() {
      console.log("test:-", this.authService.activeBusinessCase);
      const userDefinedLanguage = this.settings.language;
      if (userDefinedLanguage) {
        this.translate.use(userDefinedLanguage);
      } else {
        this.translate.use(this.config.getAutoConfiguredLanguage());
      }

      this.translate.onLangChange.subscribe(langEvent => {
        console.log('set global language ' + langEvent.lang);
        moment.locale(langEvent.lang, this.getCustomMomentLocaleSettings(langEvent.lang));
      });

    }

    getCustomMomentLocaleSettings(lang) {
      if (lang === 'en') {
        return {
          relativeTime: {
            future: 'in %s',
            past: '%s ago',
            s: '1 second',
            ss: '%d seconds',
            m: '1 minute',
            mm: '%d minutes',
            h: '1 hour',
            hh: '%d hours',
            d: '1 day',
            dd: '%d days',
            M: '1 month',
            MM: '%d months',
            y: '1 year',
            yy: '%d years'
          }
        };
      }
      if (lang === 'de') {
        return {
          relativeTime: {
            future: 'in %s',
            past: 'vor %s',
            s: '1 Sekunde',
            ss: '%d Sekunden',
            m: '1 Minute',
            mm: '%d Minuten',
            h: '1 Stunde',
            hh: '%d Stunden',
            d: '1 Tag',
            dd: '%d Tage',
            M: '1 Monat',
            MM: '%d Monate',
            y: '1 Jahr',
            yy: '%d Jahre'
          }
        };
      }
      return undefined;
    }