Source/Interface/Internationalization

=Internationalization and localization= Blender's ultimate goal is to adapt to the different languages and regional differences of its many users. However, its current state offers many language translations but does not perform other localization.

Default Locale
Although a Dutch project, Blender's default locale is "English (United States" (en-US). Even when the display language is changed, all other locale-specific preferences are assumed to be in this locale. One exception is system of measurement, which is a separate user setting.
 * Capitalization is simple Latin text-only
 * Numerals are Western Arabic
 * Collation (text sorting) is ASCII
 * Interface flow is left-to-right
 * Decimal separator is a baseline dot.
 * Digit grouping (thousands separator) is the comma.
 * Date format is MDY
 * Time format is 12-hour
 * Keyboard shortcut mnemonics in English (ctrl-S for Save)
 * Western color symbolism

Many of the above could be addressed and improved to become locale-specific or user preferences. Exceptions to this are numeral set, decimal separator, and numerical grouping character as these would complicate compatibility between Blender and Python and between users (script sharing for example).

The following sections are all related to language translation.

Automated Translation
Most (in fact, nearly all) translations are detected and done automatically by Blender’s RNA system.

So when you define a RNA property, the name and label of a panel, menu or operator, etc., you have nothing special to do, everything is handled automatically. Well, not the translation itself, of course, you’ll have to wait for the translating teams to do their job!

Apart from RNA, here is a list of functions that will automatically translate their string(s) (and which string can be caught by our fake py-xgettext code – please note that only regular strings are caught by this tool, so do not expect strings involving macro magic and the like to work here):



Please note that “printf-like” functions only translate the “format” string, it’s up to you to manage the parameters translation if needed (see below)!

When You Have to Do Something
You have to manually use macros translating (or marking for translation) your UI messages when you are directly accessing GUI drawing code, or when you are using exotic string manipulations… In one word: every time you bybass RNA for some GUI stuff.

To do so, you have three macros available, all being at least markers for xgettext:


 * N_
 * Defined in.
 * This is the marker-only macro. In other words, it does strictly nothing, it’s just here to tag a string as translatable, for the xgettext tool. Use it e.g. when you use more than one string, based on conditional checks.


 * IFACE_
 * Defined in.
 * This macro calls UI_translate_do_iface, which will translate the message if the User Preferences’ use_translate_interface is set. So it’s obviously to be used for labels.


 * TIP_
 * Defined in.
 * This macro calls UI_translate_do_tooltip, which will translate the message if the User Preferences’ use_translate_tooltips is set. As stated by its name, it’s to be used for tooltips.


 * DATA_
 * Defined in.
 * This macro UI_translate_do_new_dataname, which will translate the message if the User Preferences’ use_translate_new_dataname is set. This one is used to translate new data names (e.g. objects, materials, vgroups, etc.).
 * WARNING: This macro should only be used when creating a new data!

Additionally, you may have to edit sconscripts/cmake files to add  to the include paths (and add the -DWITH_INTERNATIONAL definition), and obviously include the   file!

Note that those macros are defined as no-op when i18n is disabled at build time.

Adding a new language in Blender
The only file to edit is the release/scripts/module/bl_i18n_utils/settings.py one, LANGUAGES var (format is quite self-explanatory). This will be used by the update_languages_menu.py script in the same dir to generate the locale/languages text file, used by Blender to know which translations are available and to generate the relevant menu…

So your main task will be to gather a team of motivated translators (currently, there are more than 19k messages, above 500k signs…)!

Contexts
Gettext’s contexts are optional strings attached to a given text to translate, designed to avoid ambiguity (as some words in a language can have different translations in another, depending on… context!).

By default, all translated strings in Blender have the default NULL xgettext context (except for operators’ names, which have the "Operator" one). You should nearly never have to bother about contexts! We are trying to keep their uses as low as possible…

If you nonetheless need to use a context, you could directly give a literal string. However, this is not a good practice, for at least two reasons:
 * A typo would go unnoticed, e.g. creating two contexts where only one should exists.
 * It’s quite hard to know whether a same (or similar) context already exists!
 * And last but not least, it would not fit into our Python i18n API!

To address this, our message searching tools support a very limited “pre-processor” feature: you can use context defines instead of literals. Here is how it works:
 * In blenfont/BLF_translation.h, bottom of the file, the contexts are defined.
 * In the same file, they are added to the BLF_I18NCONTEXTS_DESC macro, used by the py API (see below).
 * You then can use those defines as context values everywhere in code.

You can specify a context for a given RNA structure or property with the RNA define’s  and   functions. Please note that RNA context always only affects the name (or GUI label) of the element, never its description (or GUI tooltip), which is assumed detailed enough to avoid any confusion!

For non-RNA translation, you have the CTX_N_, CTX_IFACE_, CTX_TIP_ and CTX_DATA_ macros, which take as first parameter a context string (as a define, as explained above), and as second one the text to translate. Otherwise, they do the same thing as their context-less counterparts described above.

Defining multiple contexts for a single message
The typical use case is the "New" message, which is used for objects, textures, materials, particules, etc. It often translates as an adjective in foreign languages, and adjectives are often made agreed in gender, so we need a context for each kind of data.

To achieve this, the  macro was created. It does nothing, it’s only a declarative one (as e.g. the  one), it just says the i18n tools that the given msgid must be defined for all the contexts given.

Warning: Due to Python regex limitations, you cannot specify more than 16 contexts in one “call” to this macro – but you can call it several times with the same msgid!

Python Translation API
Blender’s translations API is also exposed in Python, to be used by UI scripts and addons!

Please note that here too, most messages are detected automatically. In particular,  parameter of all  ’s functions is handled as expected (most of the time, this is a complex area!). For these functions, you may also manually specify a translation context through the  parameter.

As in C code, please use pre-defined contexts (accessible through the named tuple ), as much as possible.

When you have complex strings generation (formatting, etc.), you may use the  family of functions, which mimics the matching macros described above. Note that you can import those functions as shorten names (, ,  , and  ), which are also understood by messages extraction tools. And we obviously do not have context/context-less variants in python, context parameter is just in second position and optional!