* docs: refresh docs for 3.2.0 — correct stale content, document recent features The hand-maintained VitePress docs under doc/ had drifted behind a lot of recent work. They are authored prose (not generated from the OpenAPI spec), so they need manual upkeep. This pass corrects content that was actively wrong and documents features shipped since they were last touched. Corrections (was wrong / misleading): - cli.md: every command used `node bin/foo.js`, but the scripts are TypeScript run via pnpm — copy-paste failed. Rewrote to `pnpm run --filter bin <script>`, documented ~13 previously-undocumented operator tools, and split running-vs-stopped requirements. Registered the missing `compactStalePads` script in bin/package.json so the documented invocation actually works. - stats.md: described a pre-Prometheus world. Rewrote for the gated `/stats` (JSON) and `/stats/prometheus` endpoints, the live metric set, the opt-in `scalingDiveMetrics` instruments (#7756), and `measured-core`. - admin/updates.md: removed three false "SMTP not yet wired" claims (it is, via nodemailer + the `mail.*` block), documented the `node-engine-mismatch` preflight check and the rollback/preflight failure emails, and stripped obsolete "PR 1 / PR 2" staging language now that all tiers ship. - api/http_api.md: added the undocumented `anonymizeAuthor` (GDPR Art. 17) call, fixed copyPad/movePad version annotations (1.2.8 → 1.2.9), corrected getPadID's param name (readOnlyID → roID), and dropped a reference to a non-existent `getEtherpad` API call. - skins.md: colibris is the current default, not an "experimental" skin for a future 2.0. - localization.md: bare `window._('key')` is unbound and returns undefined; recommend `window.html10n.get(...)` / data-l10n-id instead. - README.md: bumped the v2.2.5 upgrade example to v3.2.0; fixed a docker.adoc link to docker.md. - docker.md: added MAIL_*, ENABLE_METRICS, GDPR_AUTHOR_ERASURE_ENABLED, PRIVACY_BANNER_*, PUBLIC_URL, AUTHENTICATION_METHOD, ENABLE_DARK_MODE, ENABLE_PAD_WIDE_SETTINGS; fixed the SOCKETIO_MAX_HTTP_BUFFER_SIZE default (50000 → 1000000). New documentation: - configuration.md (new): how settings + `${VAR:default}` substitution work, trustProxy, and — the previously-undocumented feature — running under a subpath/ingress via x-proxy-path / X-Forwarded-Prefix / X-Ingress-Path, with the sanitizer rules and Traefik/NGINX examples. Wired into the VitePress sidebar and the index hero. - hooks_server-side.md: ccRegisterBlockElements (the server-side companion plugin authors miss), exportConvert, exportHTMLSend, createServer, restartServer, and clientReady (marked deprecated). - hooks_client-side.md: aceDrop, acePaste, handleClientTimesliderMessage_<name>. VitePress build passes. The legacy .adoc set was intentionally left in place — it still feeds the per-version doc archives published to ether.github.com at release time (bin/release.ts), so it is not dead and is out of scope here. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: address Qodo review — drop .js invocations from configuration.md and CLI help - configuration.md: the settings-override example referenced a nonexistent `node src/node/server.js`. Use the supported launcher instead (`bin/run.sh -s <file>`), and note the runtime is server.ts via tsx. - compactStalePads.ts / compactPad.ts / compactAllPads.ts: their header comments and runtime usage output still printed `node bin/*.js`, which points at files that don't exist. Switched to the documented `pnpm run --filter bin <script>` form so the --help text matches the docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.2 KiB
Localization
Etherpad provides a multi-language user interface, that's apart from your users' content, so users from different countries can collaborate on a single document, while still having the user interface displayed in their mother tongue.
Translating
We rely on https://translatewiki.net to handle the translation process for us, so if you'd like to help...
- Sign up at https://translatewiki.net
- Visit our TWN project page
- Click on
Translate Etherpad lite interface - Choose a target language, you'd like to translate our interface to, and hit
Fetch - Start translating!
Translations will be send back to us regularly and will eventually appear in the next release.
Implementation
Server-side
/src/locales contains files for all supported languages which contain the translated strings. Translation files are simple *.json files and look like this:
{ "pad.modals.connected": "Connecté."
, "pad.modals.uderdup": "Ouvrir dans une nouvelle fenêtre."
, "pad.toolbar.unindent.title": "Dèsindenter"
, "pad.toolbar.undo.title": "Annuler (Ctrl-Z)"
, "timeslider.pageTitle": "{{appTitle}} Curseur temporel"
, ...
}
Each translation consists of a key (the id of the string that is to be translated) and the translated string. Terms in curly braces must not be touched but left as they are, since they represent a dynamically changing part of the string like a variable. Imagine a message welcoming a user: Welcome, {{userName}}! would be translated as Ahoy, {{userName}}! in pirate.
Client-side
We use a language cookie to save your language settings if you change them. If you don't, we autodetect your locale using information from your browser. Then, the preferred language is fed into a library called html10n.js, which loads the appropriate translations and applies them to our templates. Its features include translation params, pluralization, include rules and a nice javascript API.
Localizing plugins
1. Mark the strings to translate
In the template files of your plugin, change all hardcoded messages/strings...
from:
<option value="0">Heading 1</option>
to:
<option data-l10n-id="ep_heading.h1" value="0"></option>
In the javascript files of your plugin, change all hardcoded messages/strings...
from:
alert ('Chat');
to:
alert(window.html10n.get('pad.chat'));
Note: Etherpad core sets up a
window._gettext-like shortcut aswindow._ = html10n.get. Because this assignment does not bindthis, calling the shortcut bare aswindow._('pad.chat')loses itsthiscontext and returnsundefined(thegetimplementation readsthis.translations). Prefer one of the patterns that actually works:
- Call the method on the object directly:
window.html10n.get('pad.chat').- Bind it once, then reuse:
const _ = window.html10n.get.bind(window.html10n);followed by_('pad.chat').Wherever possible, prefer marking up your templates with
data-l10n-idattributes (see above) instead of translating strings in JavaScript at all — html10n applies those automatically.
2. Create translate files in the locales directory of your plugin
- The name of the file must be the language code of the language it contains translations for (see supported lang codes; e.g. en ? English, es ? Spanish...)
- The extension of the file must be
.json - The default language is English, so your plugin should always provide
en.json - In order to avoid naming conflicts, your message keys should start with the name of your plugin followed by a dot (see below)
ep_your-plugin/locales/en.json
{ "ep_your-plugin.h1": "Heading 1"
}
ep_your-plugin/locales/es.json
{ "ep_your-plugin.h1": "Título 1"
}
Every time the http server is started, it will auto-detect your messages and merge them automatically with the core messages.
Overwrite core messages
You can overwrite Etherpad's core messages in your plugin's locale files.
For example, if you want to replace Chat with Notes, simply add...
ep_your-plugin/locales/en.json
{ "ep_your-plugin.h1": "Heading 1"
, "pad.chat": "Notes"
}
Customization for Administrators
As an Etherpad administrator, it is possible to overwrite core messages as well as messages in plugins. These include error messages, labels, and user instructions. Whereas the localization in the source code is in separate files separated by locale, an administrator's custom localizations are in settings.json under the customLocaleStrings key, with each locale separated by a sub-key underneath.
For example, let's say you want to change the text on the "New Pad" button on Etherpad's home page. If you look in locales/en.json (or locales/en-gb.json) you'll see the key for this text is "index.newPad". You could add the following to settings.json:
"customLocaleStrings": {
"fr": {
"index.newPad": "Créer un document"
},
"en-gb": {
"index.newPad": "Create a document"
},
"en": {
"index.newPad": "Create a document"
}
}