# KDE Internationalization (i18n) Guidelines ## Wrapping User-Visible Strings - Wrap every user-visible string in an `i18n` call. Use `i18n()` for simple messages; never present raw strings directly to the user. - For strings created before the application’s `KInstance` exists (e.g. in static initializers), use `ki18n()` which returns a translatable string object; later call `.toString()` when ready to display. ## Adding Context and Disambiguation - If a message is ambiguous or very short, provide a context comment with `i18nc("context", "text")`. For example, use `i18nc("File menu action", "Copy")` to distinguish verb and noun forms. - When pluralization and context are both needed, use `i18ncp("context", "singular", "plural", count, …)` to supply both context and plural forms. ## Plural Forms - Use `i18np("singular", "plural", count, …)` for messages that vary depending on a count. Provide both singular and plural text even if English would not require a plural. The first integer argument determines which form to use. - Do not manually pluralize with the `?:` operator; always let the i18n system handle plural rules. - When using a plural call, `%1` may be omitted in the singular string because the count itself is `%1`. ## Placeholders and Arguments - Inside the translatable string, use `%1`, `%2`, … to mark where runtime values will be inserted. The numbered placeholders correspond to additional arguments to the `i18n` function; do not use `QString::arg()` to substitute values. - Keep the number of arguments to nine or fewer; `i18n` functions support at most nine substitutions. - Placeholders must be numbered sequentially without gaps (e.g. `%1`, `%2`, `%3`); skipping a number is not allowed. - In plural forms, the first integer argument determines plural choice; other placeholders still follow the usual numbering. ## Common Pitfalls and Best Practices - Do not build user-visible sentences by concatenating multiple translated fragments. Always wrap the entire sentence in a single `i18n` call so the translator can rearrange words as needed. - Provide context for short strings, abbreviations or words that could have multiple meanings. - Avoid using `%n` (legacy gettext placeholder) in new code; use `%1`, `%2` instead. - When inserting numbers into strings, use `i18n` functions first, then supply numbers as arguments; this allows the translation system to format numbers appropriately for the locale. ## Extraction Tools and Build Integration - KDE’s build system uses a `Messages.sh` script to collect translatable strings. The script typically calls `extractrc` to extract strings from `.ui`, `.rc` and `.kcfg` files; `EXTRACT_GRANTLEE_TEMPLATE_STRINGS` for Grantlee template strings; `PREPARETIPS` for tips-of-the-day; and finally `xgettext` to extract strings from C++ and QML source files. These tools generate a `.pot` catalog that translators use. - The environment variables such as `$EXTRACTRC`, `$EXTRACT_GRANTLEE_TEMPLATE_STRINGS`, `$PREPARETIPS` and `$XGETTEXT` are provided by the build system; developers only need to list source files in the script. - Ensure that every string to be translated is reachable by these extraction tools: wrap strings in `i18n` calls in C++/QML, fill “translatable” and “comment” properties in Qt Designer for `.ui` files, and add context where necessary.