Skip to content

Commit b2fec47

Browse files
authored
Merge pull request #953 from nextcloud-libraries/feat/add-translations-to-wrapper
feat(gettext): allow to add translations to the wrapper
2 parents f94bd9b + 8cd7197 commit b2fec47

2 files changed

Lines changed: 65 additions & 15 deletions

File tree

lib/gettext.ts

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ gt.gettext('some string to translate')
1919
```
2020
*/
2121

22-
import type { AppTranslations } from './registry.ts'
22+
import type { AppTranslations, PluralFunction } from './registry.ts'
2323

2424
import { getLanguage, getPlural, translate, translatePlural } from './index.ts'
2525

@@ -43,7 +43,36 @@ export interface GettextTranslationBundle {
4343
}
4444

4545
class GettextWrapper {
46-
constructor(private bundle: AppTranslations) {
46+
private bundle: AppTranslations
47+
48+
constructor(pluralFunction: PluralFunction) {
49+
this.bundle = {
50+
pluralFunction,
51+
translations: {},
52+
}
53+
}
54+
55+
/**
56+
* Append new translations to the wrapper.
57+
*
58+
* This is useful if translations should be added on demand,
59+
* e.g. depending on component usage.
60+
*
61+
* @param bundle - The new translation bundle to append
62+
*/
63+
addTranslations(bundle: GettextTranslationBundle): void {
64+
const dict = Object.values(bundle.translations[''] ?? {})
65+
.map(({ msgid, msgid_plural: msgidPlural, msgstr }) => {
66+
if (msgidPlural !== undefined) {
67+
return [`_${msgid}_::_${msgidPlural}_`, msgstr]
68+
}
69+
return [msgid, msgstr[0]]
70+
})
71+
72+
this.bundle.translations = {
73+
...this.bundle.translations,
74+
...Object.fromEntries(dict),
75+
}
4776
}
4877

4978
/**
@@ -97,6 +126,14 @@ class GettextBuilder {
97126
return this.setLanguage(getLanguage().replace('-', '_'))
98127
}
99128

129+
/**
130+
* Register a new translation bundle for a specified language.
131+
*
132+
* Please note that existing translations for that language will be overwritten.
133+
*
134+
* @param language - Language this is the translation for
135+
* @param data - The translation bundle
136+
*/
100137
addTranslation(language: string, data: GettextTranslationBundle): this {
101138
this.translations[language] = data
102139
return this
@@ -113,20 +150,11 @@ class GettextBuilder {
113150
console.debug(`Creating gettext instance for language ${this.language}`)
114151
}
115152

116-
const translations = Object.values(this.translations[this.language]?.translations[''] ?? {})
117-
.map(({ msgid, msgid_plural: msgidPlural, msgstr }) => {
118-
if (msgidPlural !== undefined) {
119-
return [`_${msgid}_::_${msgidPlural}_`, msgstr]
120-
}
121-
return [msgid, msgstr[0]]
122-
})
123-
124-
const bundle: AppTranslations = {
125-
pluralFunction: (n: number) => getPlural(n, this.language),
126-
translations: Object.fromEntries(translations),
153+
const wrapper = new GettextWrapper((n: number) => getPlural(n, this.language))
154+
if (this.language in this.translations) {
155+
wrapper.addTranslations(this.translations[this.language])
127156
}
128-
129-
return new GettextWrapper(bundle)
157+
return wrapper
130158
}
131159
}
132160

tests/gettext.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,26 @@ msgstr "incorrect"
213213

214214
expect(translation).toEqual('correct')
215215
})
216+
217+
it('can add translations afterwards', () => {
218+
const pot = `msgid ""
219+
msgstr ""
220+
"Last-Translator: Translator, 2020\n"
221+
"Content-Type: text/plain; charset=UTF-8\n"
222+
"Language: sv\n"
223+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
224+
225+
msgid "abc"
226+
msgstr "def"
227+
`
228+
const gt = getGettextBuilder()
229+
.setLanguage('sv')
230+
.build()
231+
232+
expect(gt.gettext('abc')).toBe('abc')
233+
234+
gt.addTranslations(po.parse(pot))
235+
236+
expect(gt.gettext('abc')).toBe('def')
237+
})
216238
})

0 commit comments

Comments
 (0)