Skip to content

Commit b194f86

Browse files
authored
Merge pull request #738 from devforth/feature/AdminForth/1995/use-local-i18n-plugin-on-live-
live-demo: i18n-static AdminForth/1995/use-local-i18n-plugin-on-live-
2 parents de43a02 + 8f7eafc commit b194f86

33 files changed

Lines changed: 13805 additions & 981 deletions
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
name: adminforth-i18n-static
3+
description: "Use when asked to translate AdminForth admin panel UI, fill missing translations, or add a new admin language with @adminforth/i18n-static plugin (JSON files per language)."
4+
user-invocable: true
5+
---
6+
7+
# AdminForth Static Translations Workflow
8+
9+
## How Translations Work
10+
11+
- Every supported language has its own flat JSON file `<translationsDir>/<language code>.json` (`langs/` by default), e.g. `langs/uk.json`, `langs/pt-BR.json`.
12+
- Keys are original English strings from admin UI, values are translations: `{ "Save": "Зберегти" }`.
13+
- Empty value means "not translated yet", admin shows the original English key instead.
14+
- Files are read on every request, so edits are visible after page reload without restart.
15+
16+
## Workflow
17+
18+
1. Sync keys first, so every language file contains all actual keys:
19+
`pnpm exec adminforth-i18n-static sync` (or `npx adminforth-i18n-static sync` for npm).
20+
It prints every language file with counts: `total`, `added`, `stale` and `untranslated`.
21+
2. Fill empty values in language files the user asked for (all non-English files if not specified).
22+
3. Run sync again and make sure `untranslated` is 0 for translated files and there is no `wrong plural` warning. Fix every listed plural string.
23+
24+
## Translation Rules
25+
26+
- Never change, add or remove keys, only write values. Keep keys order.
27+
- Do not translate `en.json`: sync fills its values with the keys (original English strings). Change its values only if the user asks to rephrase English texts.
28+
- Do not touch non-empty values unless the user asks to fix them.
29+
- Do not remove stale keys (reported as `stale`), the user decides about them.
30+
- Keep variables in curly brackets exactly as in the key and do not translate them: `"Hello {name}"` → `"Привіт {name}"`, never `{ім'я}`.
31+
- Keys with `|` are plural forms. Keep the same number of forms separated by `|`, except Slavic languages
32+
(uk, ru, be, pl, cs, sk, bg, sr, hr, mk, sl) which need 4 forms "zero | singular | 2-4 | 5+",
33+
e.g. `"apple | apples"` in `uk.json` becomes `"яблук | яблуко | яблука | яблук"`.
34+
- For codes with region (e.g. `pt-BR`) use regional spelling, punctuation and formatting.
35+
- Keep translations short: they are UI labels, buttons and messages of an admin panel.
36+
- If meaning of a key is not clear (short words like `Show`, `of`, `to`, `Your` or sentence fragments), find where it is used:
37+
search for the key in `$t('...')` / `t('...')` calls in project custom components and in AdminForth sources
38+
(`node_modules/adminforth/dist/spa/src`, `node_modules/@adminforth/*/dist/custom`). Translate by context: a button, a label
39+
or a part of a sentence glued with other text in the template, then the translation must fit the whole phrase.
40+
- Keep JSON valid with 2 spaces indentation.

‎live-demo/app/globalPlugins.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ export const adminForthAgent = new AdminForthAgent({
2828
defaultVoice: 'alloy',
2929
defaultSpeed: 1.25,
3030
}),
31-
placeholderMessages: async ({ httpExtra }: any) => getLocalizedPlaceholderMessages({
32-
completionAdapter: fastCompletionAdapter as any,
33-
httpExtra,
31+
placeholderMessages: async ({ headers }) => getLocalizedPlaceholderMessages({
32+
completionAdapter: fastCompletionAdapter,
33+
headers,
3434
}),
3535
modes: [
3636
{

‎live-demo/app/index.ts‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@ import fs from 'fs';
66
import usersResource from "./resources/users";
77
import apartmentsResource from "./resources/apartments";
88
import auditLogsResource from "./resources/auditLogs"
9-
import translations from "./resources/translations";
9+
// old DB-based i18n plugin, replaced by I18nStaticPlugin in globalPlugins
10+
// import translations from "./resources/translations";
1011
import sessionsResource from './resources/agent_resources/sessions';
1112
import turnsResource from './resources/agent_resources/turns';
1213
import checkpointsResource from './resources/agent_resources/checkpoints';
1314
import jobs_resource from './resources/jobs';
1415
import { randomUUID } from 'crypto';
1516
try { fs.mkdirSync('db') } catch (e) {}
1617
import { adminForthAgent } from './globalPlugins';
18+
import I18nStaticPlugin from '@adminforth/i18n-static';
1719

1820
let db;
1921

@@ -65,7 +67,7 @@ new AdminForth({
6567
apartmentsResource,
6668
usersResource,
6769
auditLogsResource,
68-
translations,
70+
// translations,
6971
sessionsResource,
7072
turnsResource,
7173
checkpointsResource,
@@ -90,11 +92,11 @@ new AdminForth({
9092
icon: 'flowbite:home-solid',
9193
resourceId: 'aparts',
9294
},
93-
{
94-
label: 'Translations',
95-
icon: 'material-symbols:translate',
96-
resourceId: 'translations',
97-
},
95+
// {
96+
// label: 'Translations',
97+
// icon: 'material-symbols:translate',
98+
// resourceId: 'translations',
99+
// },
98100
]
99101
},
100102
{
@@ -130,7 +132,14 @@ new AdminForth({
130132
},
131133
],
132134
globalPlugins: [
133-
adminForthAgent
135+
adminForthAgent,
136+
new I18nStaticPlugin({
137+
supportedLanguages: [
138+
'en', 'uk', 'ja', 'fr', 'es', 'pt-BR',
139+
'de', 'it', 'pt', 'nl', 'pl', 'tr', 'cs', 'sv', 'da', 'fi',
140+
'ro', 'hu', 'el', 'bg', 'zh', 'ko', 'ar', 'he', 'hi', 'vi',
141+
],
142+
}),
134143
]
135144
});
136145

0 commit comments

Comments
 (0)