Skip to content

Commit a1d6ca7

Browse files
committed
feat(gettext): allow to add translations to the wrapper
This allows us to only register what is needed. Normally you would register everything at once, but for performance reasons the `nextcloud-vue` library only registers the translations of components that are really used. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 7ff2598 commit a1d6ca7

2 files changed

Lines changed: 64 additions & 15 deletions

File tree

lib/gettext.ts

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const gt = getGettextBuilder()
1818
gt.gettext('some string to translate')
1919
```
2020
*/
21-
import type { AppTranslations } from './registry.ts'
21+
import type { AppTranslations, PluralFunction } from './registry.ts'
2222
import { getLanguage, getPlural, translate, translatePlural } from './index.ts'
2323

2424
export interface GettextTranslation {
@@ -69,6 +69,13 @@ class GettextBuilder {
6969
return this.setLanguage(getLanguage().replace('-', '_'))
7070
}
7171

72+
/**
73+
* Register a new translation bundle for a specified language.
74+
*
75+
* Please note that existing translations for that language will be overwritten.
76+
* @param language - Language this is the translation for
77+
* @param data - The translation bundle
78+
*/
7279
addTranslation(language: string, data: GettextTranslationBundle): this {
7380
this.translations[language] = data
7481
return this
@@ -84,29 +91,49 @@ class GettextBuilder {
8491
console.debug(`Creating gettext instance for language ${this.language}`)
8592
}
8693

87-
const translations = Object.values(this.translations[this.language]?.translations[''] ?? {})
88-
.map(({ msgid, msgid_plural: msgidPlural, msgstr }) => {
89-
if (msgidPlural !== undefined) {
90-
return [`_${msgid}_::_${msgidPlural}_`, msgstr]
91-
}
92-
return [msgid, msgstr[0]]
93-
})
94-
95-
const bundle: AppTranslations = {
96-
pluralFunction: (n: number) => getPlural(n, this.language),
97-
translations: Object.fromEntries(translations),
94+
const wrapper = new GettextWrapper((n: number) => getPlural(n, this.language))
95+
if (this.language in this.translations) {
96+
wrapper.addTranslations(this.translations[this.language])
9897
}
99-
100-
return new GettextWrapper(bundle)
98+
return wrapper
10199
}
102100

103101
}
104102

105103
class GettextWrapper {
106104

105+
private bundle: AppTranslations
106+
107107
constructor(
108-
private bundle: AppTranslations,
108+
pluralFunction: PluralFunction,
109109
) {
110+
this.bundle = {
111+
pluralFunction,
112+
translations: {},
113+
}
114+
}
115+
116+
/**
117+
* Append new translations to the wrapper.
118+
*
119+
* This is useful if translations should be added on demand,
120+
* e.g. depending on component usage.
121+
*
122+
* @param bundle - The new translation bundle to append
123+
*/
124+
addTranslations(bundle: GettextTranslationBundle): void {
125+
const dict = Object.values(bundle.translations[''] ?? {})
126+
.map(({ msgid, msgid_plural: msgidPlural, msgstr }) => {
127+
if (msgidPlural !== undefined) {
128+
return [`_${msgid}_::_${msgidPlural}_`, msgstr]
129+
}
130+
return [msgid, msgstr[0]]
131+
})
132+
133+
this.bundle.translations = {
134+
...this.bundle.translations,
135+
...Object.fromEntries(dict),
136+
}
110137
}
111138

112139
/**

tests/gettext.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,26 @@ msgstr "incorrect"
214214
expect(translation).toEqual('correct')
215215
})
216216

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+
})
238+
217239
})

0 commit comments

Comments
 (0)