docs/translations.md
Translate the widget
The applet ships Italian (it), French (fr), German (de), Spanish (es),
and Brazilian Portuguese (pt_BR).
It follows Plasma's language preferences and uses English when no matching
catalog exists. Known session states and sources, and structured pace forecasts,
use the applet's translation catalog. Provider names remain unchanged.
CLI text and localization
The CLI 0.56.2 JSON contracts provide the inputs for these translations:
AgentSessiondefinesactive/idlestates andcli,desktopApp,ide, andunknownsources. The widget also translates its existingrunningandworkingcompatibility values. Unknown future values retain their display text.CLIRenderer.pacePayloademitsstage,deltaPercent,expectedUsedPercent,willLastToReset, andetaSeconds.PacePresentation.jsvalidates these fields and returns semantic parts;main.qmltranslates them. The widget does not parse the Englishsummaryor recalculate the CLI forecast. A summary-only payload retains its bounded, redacted text as a compatibility fallback.
Free-form incident descriptions, provider detail titles/rows/chart labels, extra-window titles, CLI lane titles for providers without a translated lane label, reset-description fallbacks, and CLI error messages can still appear in English. Translating them reliably needs official CLI message identifiers with typed arguments, or a documented locale-aware output contract. Do not translate arbitrary provider text by matching English phrases. The CLI's prose-only pace headroom hint also needs a structured presentation field before the widget can localize it; it is not appended to the structured pace summary.
Track the remaining structured CLI localization work in TODO.
In Italian, settings use "Diagnostica" and "Finestra a comparsa". Technical terms such as "provider", "account", and "token" remain unchanged. Spanish instructions use the formal address consistently. Brazilian Portuguese uses "Padrão" for the Standard panel style.
Translate labels against their displayed values. "Code review remaining" labels
a remaining quota percentage, and "Included plan" labels usage included in a
plan. Neither describes a count of reviews or a separate included subscription.
The panel's "behind pace" message means the CLI predicts quota exhaustion before
reset (willLastToReset === false). Translate it as excessive consumption, not
as consumption below the expected pace.
Install GNU gettext and Python 3 before running the commands below. Run them from the repository root.
Update a catalog
Regenerate the template after changing user-facing QML strings:
| 1 | make translations |
Merge the template into the language you are updating:
| 1 | msgmerge --update --backup=none --no-fuzzy-matching po/it.po po/codexbar-plasma.pot |
Edit the msgstr entries in po/it.po with a PO editor or text editor. Keep
msgid and msgid_plural unchanged. Source references above each entry point
to the QML that gives the message its context.
- Keep every
%1,%2, and other numbered argument. You may reorder them. - Translate every plural form, including short duration labels. Keep the
language's
Plural-Formsheader accurate. - Integer token, request, and point counts use plural messages. The separate
%1 tokens,%1 requests, and%1 pointsentries format compact counts such as1Kand4.3B. Keep those abbreviations in the numbered argument; do not treat the leading1as a singular count. - Keep CodexBar, provider brands, command names, paths, and URLs unchanged.
- Translate the
msgid "en"entry whose context starts with "BCP 47 language tag of this translation" to the catalog's own tag, such asitorpt-BR. AI Insights writes in the language named there, so it must match the catalog's language exactly and never be left empty. - Use short labels for the panel and tabs. Check longer text in the popup.
- Resolve fuzzy entries and translate empty entries before submitting.
Run the catalog checks and build the distributable:
| 1 | make check |
| 2 | make package |
The build uses the plugin ID in metadata.json to name the catalog. For this
applet the path inside the archive is
contents/locale/it/LC_MESSAGES/plasma_applet_app.codexbar.plasma.mo.
Only the PO sources are committed. The generated catalogs are bundled with the
widget and need no separate system-wide installation. This follows the
Plasma translation domain convention.
Preview a translation
From a Plasma 6 graphical session, run a preview with synthetic data:
| 1 | make smoke SMOKE_ARGS='--scenario localization-it' |
Use localization-fr, localization-de, localization-es, or localization-pt_BR
for the other catalogs. Install or generate the corresponding UTF-8 locale first:
it_IT.UTF-8, fr_FR.UTF-8, de_DE.UTF-8, es_ES.UTF-8, or pt_BR.UTF-8.
The CI container generates all five locales.
The preview uses isolated settings and a private D-Bus session. It checks translated overview and settings text, singular and plural forms, a provider's pace summary, and session state/source labels. Count checks cover zero, one, multiple items, compact values above the integer range, and cost summaries. It saves a screenshot of the Sessions tab. It does not change your desktop language or installed widget. Review the screenshots for clipped labels and awkward wrapping.
Add a language
Create a catalog from the current template. For example, for Dutch:
| 1 | msginit --no-translator --locale=nl --input=po/codexbar-plasma.pot --output-file=po/nl.po |
Set the Language, Language-Team, Last-Translator, PO-Revision-Date, and
Plural-Forms headers. Complete all translations and follow the checks above.
Packaging discovers po/*.po automatically.
Add a translated Description[language] to metadata.json for the widget
picker. Add the language to the catalog assertions in
tests/test_translations.py, the preview locale map in scripts/smoke_popup.py,
and the scenarios in scripts/smoke/fixture_cli.py. Supply expected popup and
plural labels in scripts/smoke/Capture.qml and generate the locale in
scripts/install-ci-dependencies.sh.
Include the PO file, metadata, checks, and updated language lists in one pull
request. Do not commit .mo files or change the CLI to translate its output.