mirror of https://github.com/ghostfolio/ghostfolio
committed by
Thomas
3 changed files with 70 additions and 0 deletions
@ -0,0 +1,9 @@ |
|||||
|
import { Module } from '@nestjs/common'; |
||||
|
|
||||
|
import { I18nService } from './i18n.service'; |
||||
|
|
||||
|
@Module({ |
||||
|
providers: [I18nService], |
||||
|
exports: [I18nService] |
||||
|
}) |
||||
|
export class I18nModule {} |
@ -0,0 +1,59 @@ |
|||||
|
import * as fs from 'fs'; |
||||
|
import { join } from 'path'; |
||||
|
import { Injectable } from '@nestjs/common'; |
||||
|
import * as cheerio from 'cheerio'; |
||||
|
|
||||
|
@Injectable() |
||||
|
export class I18nService { |
||||
|
private localesPath = join(__dirname, 'assets/locales/'); |
||||
|
private localeRegex = /^messages\.[a-z]{2}\.xlf$/; |
||||
|
private translations: { [locale: string]: cheerio.CheerioAPI } = {}; |
||||
|
|
||||
|
constructor() { |
||||
|
this.loadFiles(); |
||||
|
} |
||||
|
|
||||
|
public getTranslation({ |
||||
|
id, |
||||
|
locale |
||||
|
}: { |
||||
|
id: string; |
||||
|
locale: string; |
||||
|
}): string { |
||||
|
const $ = this.translations[locale]; |
||||
|
if (!$) { |
||||
|
throw new Error(`Translation not found for locale '${locale}'`); |
||||
|
} |
||||
|
|
||||
|
const translatedText = $(`trans-unit[id="${id}"] > target`).text(); |
||||
|
if (!translatedText) { |
||||
|
throw new Error( |
||||
|
`Translation not found for id '${id}' in locale '${locale}'` |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return translatedText; |
||||
|
} |
||||
|
|
||||
|
private loadFiles() { |
||||
|
try { |
||||
|
const files = fs.readdirSync(this.localesPath, 'utf-8'); |
||||
|
for (const file of files) { |
||||
|
if (!this.localeRegex.test(file)) continue; |
||||
|
if (!fs.existsSync(`${this.localesPath}${file}`)) { |
||||
|
throw new Error(`File: ${file} not found`); |
||||
|
} else { |
||||
|
const xmlData = fs.readFileSync(`${this.localesPath}${file}`, 'utf8'); |
||||
|
this.translations[file.split('.')[1]] = this.parseXml(xmlData); |
||||
|
} |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.log(error); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private parseXml(xmlData: string): cheerio.CheerioAPI { |
||||
|
const selectorFn = cheerio.load(xmlData, { xmlMode: true }); |
||||
|
return selectorFn; |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue