Localization refactoring:

* the front-end now use global constants, based on the translation key
* build-client.js use the ESBuild "define" directive to replace these
  globals at compile time, by the english value
* build:client must now be called after build:languages
* moving the loadLoc and loc backend functions in a separate lib
This commit is contained in:
John Livingston
2023-06-12 19:26:28 +02:00
parent 7285c8b0a8
commit f73ccbbf7e
12 changed files with 199 additions and 93 deletions

43
server/lib/loc.ts Normal file
View File

@ -0,0 +1,43 @@
import { resolve } from 'path'
import { existsSync, promises as fsPromises } from 'fs'
const locContent: Map<string, string> = new Map<string, string>()
/**
* Currently, the Peertube plugin system assumes that settings strings
* are localized in english, and will be translated on front-end.
* This system make it hard to have complex strings (with html, newlines, ...).
* See https://github.com/Chocobozzz/PeerTube/issues/4523
*
* Waiting for a better solution, we implemented a custom solution:
* - We are using keys to identify strings
* - the `loc` function gets the english segment for the key
* - the build-languages.js script builds all needed files.
* @param key The key to translate
*/
function loc (key: string): string {
return locContent.get(key) ?? key
}
async function loadLoc (): Promise<void> {
const filePath = resolve(__dirname, '..', '..', 'languages', 'en.reference.json')
if (!existsSync(filePath)) {
throw new Error(`File ${filePath} missing, can't load plugin loc strings`)
}
const content = await fsPromises.readFile(filePath, 'utf8')
const json = JSON.parse(content ?? '{}')
if (typeof json !== 'object') {
throw new Error(`File ${filePath} invalid, can't load plugin loc strings`)
}
for (const k in json) {
const v = json[k]
if (typeof v === 'string') {
locContent.set(k, v)
}
}
}
export {
loc,
loadLoc
}

View File

@ -1,50 +1,11 @@
import type { RegisterServerOptions } from '@peertube/peertube-types'
import { ensureProsodyRunning } from './prosody/ctl'
import type { ConverseJSTheme } from '../../shared/lib/types'
import { existsSync, promises as fsPromises } from 'fs'
import { resolve } from 'path'
const locContent: Map<string, string> = new Map<string, string>()
/**
* Currently, the Peertube plugin system assumes that settings strings
* are localized in english, and will be translated on front-end.
* This system make it hard to have complex strings (with html, newlines, ...).
* See https://github.com/Chocobozzz/PeerTube/issues/4523
*
* Waiting for a better solution, we implemented a custom solution:
* - We are using keys to identify setting strings
* - the `loc` function gets the english segment for the key
* - the build-languages.js script builds all needed files.
* @param key The key to translate
*/
function loc (key: string): string {
return locContent.get(key) ?? key
}
async function loadLoc (): Promise<void> {
const filePath = resolve(__dirname, '..', '..', 'languages', 'en.reference.json')
if (!existsSync(filePath)) {
throw new Error(`File ${filePath} missing, can't load plugin settings`)
}
const content = await fsPromises.readFile(filePath, 'utf8')
const json = JSON.parse(content ?? '{}')
if (typeof json !== 'object') {
throw new Error(`File ${filePath} invalid, can't load plugin settings`)
}
for (const k in json) {
const v = json[k]
if (typeof v === 'string') {
locContent.set(k, v)
}
}
}
import { loc } from './loc'
async function initSettings (options: RegisterServerOptions): Promise<void> {
const { peertubeHelpers, registerSetting, settingsManager } = options
await loadLoc()
// ********** IMPORTANT NOTES
registerSetting({
type: 'html',

View File

@ -6,6 +6,7 @@ import { initRouters } from './lib/routers/index'
import { initFederation } from './lib/federation/init'
import { prepareProsody, ensureProsodyRunning, ensureProsodyNotRunning } from './lib/prosody/ctl'
import { unloadDebugMode } from './lib/debug'
import { loadLoc } from './lib/loc'
import decache from 'decache'
// FIXME: Peertube unregister don't have any parameter.
@ -20,6 +21,9 @@ async function register (options: RegisterServerOptions): Promise<any> {
throw new Error('Your peertube version is not correct. This plugin is not compatible with Peertube < 3.2.0.')
}
// First: load languages files, so we can localize strings.
await loadLoc()
await migrateSettings(options)
await initSettings(options)