allow translation "patching" for english

Massimo Melina committed Apr 11, 2024 at 11:29 UTC b92aa9b574a63e37d2d4844be1bb82c499990236
2 files changed +23 -4
dev-plugins.md
+12
@@ -403,6 +403,18 @@ is not used by another plugin, or even HFS in the future.
403 If you need to pass variables in the text, introduce a third parameter in the middle.
404 Eg: `HFS.t('myPlugin_filter_count', {n:filteredVariable}, "{n} filtered")`
405
406 +### Language customization
407 +
408 +One can change a specific text by overriding existing translation. Example: you want to change the text for "Options" to "Settings".
409 +If you want to override for a specific language, for example english with language-code `en`:
410 +
411 +```js
412 +HFS._.set(HFS.lang, 'en.translate.Options', 'Settings')
413 +```
414 +
415 +This works because all translations are stored inside `HFS.lang`.
416 +Using `HFS._.set` is not necessary, but in this case is convenient, because the language-code key may not exist.
417 +
418 ## API version history
419
420 - 8.8 (v0.53.0)
frontend/src/i18n.ts
+11 -4
@@ -3,12 +3,19 @@
3 import { findDefined, getHFS } from './misc'
4 import { createElement as h } from 'react'
5 import { proxy, useSnapshot } from 'valtio'
6 +import { watch } from 'valtio/utils'
7
8 const translations = getHFS().lang || {} // all dictionaries
8 -const state = proxy<{ langs: string[], embedded: string }>({
9 +const state = proxy({
10 embedded: '',
11 langs: Object.keys(translations)
12 })
13 +const searchLangs: string[] = []
14 +watch(get => {
15 + const snapshot = get(state)
16 + searchLangs.splice(0, Infinity, ...snapshot.langs, snapshot.embedded) // replace completely
17 +})
18 +
19 const warns = new Set() // avoid duplicates
20
21 // the hook ensures translation is refreshed when language changes
@@ -33,11 +40,11 @@ export function t(keyOrTpl: string | string[] | TemplateStringsArray, params?: a
40 }
41 let found
42 let selectedLang = '' // keep track of where we find the translation
36 - const { langs, embedded } = state
43 + const { embedded, langs } = state
44 for (const key of keys) {
38 - found = findDefined(langs, lang => translations[selectedLang=lang]?.translate?.[key])
45 + found = findDefined(searchLangs, lang => translations[selectedLang=lang]?.translate?.[key])
46 if (found) break
40 - if (selectedLang && langs[0] !== embedded && !warns.has(key)) {
47 + if (!warns.has(key) && langs.length && langs[0] !== embedded) {
48 warns.add(key)
49 console.debug("miss i18n:", key)
50 }