Using toolforge_i18n in a non-Flask tool

This section documents how to use toolforge_i18n in a tool that does not use the Flask framework. The library does not yet include a lot of support for other frameworks, but it should be possible to make it work. If you put together a working integration with another framework, please consider contacting the toolforge_i18n maintainer(s) about adding it to the library.

To set up the tool, you’ll want to follow similar steps as in Setting up toolforge_i18n in a Flask tool. Make sure you only add toolforge_i18n to your dependencies (without the [Flask] extra). The tool_translations_config.py and i18n/ directory should look the same. The ToolforgeI18n and message imports will both not be available; instead, you’ll want to import at least load_translations and I18nFormatter:

from toolforge_i18n import I18nFormatter, load_translations

Somewhere in the initialization code of the tool, you’ll want to load the translations:

import tool_translations_config
translations, documentation = load_translations(tool_translations_config.config)

(You probably won’t need the documentation; load_translations returns it, but feel free to discard it.) Skip the step about the <html> tag – you might want to do something similar in your tool, but push_html_lang and pop_html_lang are Flask-specific.

When handling an incoming request, you’ll need to determine the interface language somehow, e.g. based on the user’s preferences or the request’s URL parameters and headers. The functions lang_mw_to_bcp47 and lang_bcp47_to_mw may be useful to convert between language codes used by MediaWiki and ones used by HTML and HTTP.

To use a message, look up the message string in the translations based on the request language you determined (perhaps using lang_fallbacks if the message is not defined in that language), and format it using an I18nFormatter. The formatter should be created and used like this:

# assume `language` is a MediaWiki language code
formatter = I18nFormatter(
    locale_identifier=tool_translations_config.config.language_code_to_babel(language),
    get_gender=tool_translations_config.config.get_gender,
)
# assume `message` is a message string from `translations`
# optionally, `kwargs` contains message variables
formatted = formatter.format(message, **kwargs)

If your framework supports integrating with MarkupSafe, it’s even better to wrap the message passed into the formatter in Markup, so that unsafe strings in the kwargs are automatically escaped:

formatted = cast(Markup, formatter.format(Markup(message), **kwargs))

During ongoing development of the tool, you’ll want to follow similar steps as in Developing a Flask tool using toolforge_i18n to work on messages, except that the message function is not available – you’ll have to format messages yourselves, as shown above. Everything else about the message strings in i18n/ and variable formatting still applies, as do the remarks on HTML formatting and potentially having to adjust your TranslationsConfig; the section on HTML escaping only applies if you can integrate with MarkupSafe, as mentioned above. (It’s strongly recommended to use MarkupSafe integration if at all possible.)