diff --git a/doc/support-multi-language.md b/doc/support-multi-language.md index e5c53826..169758a4 100644 --- a/doc/support-multi-language.md +++ b/doc/support-multi-language.md @@ -1,135 +1,107 @@ # Supporting Multiple Languages in the Web UI -The firmware uses a client-side i18n approach -all translations are stored in a single JavaScript dictionary embedded in the firmware. -No server-side changes are needed. +The firmware uses a client-side i18n approach: all translations are stored +in one JavaScript dictionary embedded in the firmware. No server-side +changes are needed. ## Architecture -All translation logic lives in `html/i18n.js`. The file contains: +All translation logic lives at the top of `html/app.js`: -- A `LANG` object with one sub-object per language (`en`, `ja`, ...) -- Language auto-detection (browser language → `localStorage` override) -- `t(key)` — look up a translated string -- `setLang(lang)` — switch language and update the page -- `applyTranslation(el)` — apply translation to one DOM element +- A `LANG` object with one sub-object per language (`en`, `ja`, `zh`) +- Language auto-detection (browser language, overridden by the + `rtl_lang` key in `localStorage`, which the language selector in the + page header writes) +- `t(key, vars)` looks up a translated string; `{name}` placeholders in + the string are replaced from `vars`, e.g. `t("v_del_q", {n: vid})` +- `i18nApply()` applies the dictionary to the static markup once at load -Translation keys are **flat strings** (no nesting). The English keys in `LANG.en` also serve as the fallback when a key is missing in another language. +Translation keys are flat strings. The English entry is the fallback when +a key is missing in another language, and the key itself is the fallback +when it is missing everywhere. + +Changing the language stores the choice and reloads the page, so every +dynamically built table is rebuilt in the new language. + +`login.html` is served before authentication and does not load `app.js`; +it carries its own five strings per language in an inline table. ## How to Add a New Language -### 1. Add a dictionary entry in `html/i18n.js` +### 1. Add a dictionary entry in `html/app.js` -Append a new sub-object to the `LANG` object. Every key from `LANG.en` must be present: +Append a sub-object to `LANG`. Every key from `LANG.en` should be present: ```js -var LANG = { - en: { - nav_overview: 'Overview', - nav_port_config: 'Port Configuration', - // ... all keys for English - }, - ja: { - nav_overview: '概要', - nav_port_config: 'ポート設定', - // ... all keys for Japanese - }, - LANGCODE: { // ← add your language here - nav_overview: '...', - nav_port_config: '...', - // ... translate every key - }, +var LANG={ +en:{ +nav_dash:"Dashboard", +... +}, +LANGCODE:{ // add your language here +nav_dash:"...", +... +} }; ``` -### 2. Add the language to the navigation sidebar +### 2. Add the language to the selector in `html/index.html` -In `html/navigation.js`, add an `" +```html + ``` -Replace with: +### 3. Add the login strings in `html/login.html` -```js -+ "" -``` +The inline table there holds, per language: page title, subtitle, +password label, button label, wrong-password message. -### 3. Verify auto-detection +### 4. Verify auto-detection -The language detection code in `i18n.js` reads `navigator.language` and normalises it to the first two characters: - -```js -var browser = (navigator.language || navigator.userLanguage || 'en').substring(0, 2); -return LANG[browser] ? browser : 'en'; -``` - -If the two-letter code matches a key in `LANG`, it will be auto-selected. No changes needed here. +The detection normalises `navigator.language` to its first two +characters and selects that language if `LANG` has it, otherwise English. ## Two Translation Mechanisms -### (A) `data-i18n` attribute (declarative — for HTML) - -Add `data-i18n="key_name"` to any HTML element. The English text goes in the element content as a fallback: +### (A) `data-i18n` attributes (declarative, for HTML) ```html -

Port Configuration

- - -Port Configuration +

Port configuration

+ + ``` -On page load, `applyTranslation()` sets: +- `data-i18n` sets the element's text content +- `data-i18n-t` sets the `title` attribute (tooltip) +- `data-i18n-p` sets the `placeholder` attribute -- `el.value` for `` -- `el.textContent` for `