Update Locale
Keeping the GNU gettext .po files of an application in sync with the strings you mark for translation — scattered across YAML metadata and Delphi code — is tedious by hand. KIDEx automates it: with one command it scans the project's metadata and sources, extracts every translatable string, and merges the result into a language's default.po — preserving the translations already done.
This is the recommended way to build and maintain the .po files of a Kittox application: you mark strings with _(...) (and use the standard label nodes), then re-run this command whenever metadata or code changes. Translators working in parallel never lose their work.
Why this matters
A typical Kittox application has hundreds of strings scattered across:
- YAML metadata —
DisplayLabel,PluralDisplayLabel,Hint,AllowedValueslabels, button/ToolView captions, dialog titles, filter labels - Delphi source — strings inside
_('...')calls inControllers.pas,Rules.pas,UseKitto.pasand your own units
Manually keeping the .po files aligned with all of this is impractical. KIDEx does it in seconds with two extraction passes merged into a single .po:
What it extracts
1. YAML metadata
KIDEx walks the loaded metadata catalog — Models, Views, Layouts and the top-level Config *.yaml files — and collects a node's value when either:
- the node name is one of the configured localizable keys — by default
AppTitle,ConfirmationMessage,DisplayLabel,Folder,FreeSearch,Hint,PluralDisplayLabel(list read fromLocalization/Yaml/DefaultKeyNamesin KIDEx'sConfig.yaml); or - the node value is already wrapped as
_(...).
The _(...) wrapper is stripped, so the msgid is the plain text (e.g. DisplayLabel: _(Bar Chart) → msgid Bar Chart).
Wrap everything you want translated
The name list above is intentionally small. Any other translatable YAML value must be wrapped in _(...) to be picked up — view Title, ToolViews labels, filter captions, AllowedValues descriptions (never the DB codes), etc. For model fields the recommended form is an explicit DisplayLabel: _(English), which is both extracted and self-documenting.
2. Delphi sources
KIDEx then runs the bundled dxgettext (dxgettext.exe --delphi) over the project's sibling Source\ folder, extracting every _('...') / gettext string from your Delphi units into a temporary catalog.
3. Merge
The two passes are merged into the target language's default.po with msgcat: existing msgstr values are kept, and strings found for the first time are added with an empty translation, ready to be filled in.
The operation is non-destructive — it only adds missing msgids; it never overwrites an existing translation.
Scope
- It maintains the application catalog only —
default.poper language. The framework strings (Kitto.po) are shipped translated by Ethea and are not regenerated here. - It works on one language at a time: you run it on a specific
default.po.
Prerequisites
- A project open in KIDEx.
- The bundled dxgettext tools (
dxgettext.exeandmsgcat.exe), shipped underKide\Bin\dxgettexttools. The folder is read fromLocalization/dxgettext/Pathin KIDEx'sConfig.yaml(default%APP_PATH%dxgettexttools) and shown read-only in the dialog. - Project layout:
Home\Metadata\(the YAML), a siblingSource\folder (the Delphi units), and the targetHome\Locale\<lang>\LC_MESSAGES\default.po. The New Project Wizard creates the locale skeleton.
Running it
- In the KIDEx file tree, expand the project's Locales node — each language appears with its
default.po. - Right-click the language you want and choose Update…. The Update Locale dialog opens, showing the target
.poand the dxgettext tools path. - Click Update. The status line reports progress and ends with
Done.
Repeat for each language you ship.
After the update: translate and compile
KIDEx updates the .po but does not compile the .mo. Newly-found strings appear with an empty msgstr:
- Open
Home\Locale\<lang>\LC_MESSAGES\default.poin Poedit (or any gettext editor). - Translate the empty entries.
- Save — Poedit writes
default.moautomatically (or runmsgfmt default.po -o default.mo). The runtime reads the.mo.
See Localization for the runtime side (file structure, .mo, language selection).
Adding a new language
- Create
Home\Locale\<lang>\LC_MESSAGES\(e.g.de,es,pt,pt_BR) and copy an existingdefault.pointo it — or start from an empty file. - Run Update… on it to fill it with all current msgids.
- Translate and compile as above.
The login/menu language switcher is built from the locale subfolders, so the new language appears automatically once its folder exists.
Notes & limitations
- Non-destructive: existing translations are preserved; the update only adds new (empty) msgids.
- It does not mark changed strings as
fuzzy, nor move removed strings to an obsolete section — cleaning up stale entries is a manual/translator task (e.g. Poedit's Catalog → Purge deleted translations). - The top-level Resources → Update Locale Files… main-menu entry is currently a placeholder; use the per-language Update… tree action described above.
See also
- Localization — runtime localization,
.po/.mostructure, language selection - How To: Localize an Application — the end-to-end workflow
- New Project Wizard — creates the
Home\Localeskeleton
