From BlenderWiki

Jump to: navigation, search
Note: This is an archived version of the Blender Developer Wiki. The current and active wiki is available on wiki.blender.org.

Notes for Developers

First of all, you are strongly recommended to read the Implementation Design before reading this page, as that page contains important foundations.

For C Code

Foundations

Include the header, which contains _() and N_() Macro:

#include "BLF_api.h"

If the compiler complains that no "BLF_api.h" has been found, please edit the right CMakelists.txt and SConstruct to add the header directory /source/blender/blenfont.

And of course, make sure that you have configured the building system with INTERNATIONAL enabled, and call any i18n functions after BLF_lang_set("").

I18N Approaches

- For simple texts, try to use _("msgid") directly. It combines marking and runtime translation together.

- For texts that cannot be stored localizedly, for example, those ID strings which should be kept in English while also needed to be displayed in the UI, just use N_("msgid") to mark them, and do the runtime translation at the last moment.

- For texts in some arrays or structs initialization that cannot contain a function call like _(), use N_("msgid") to mark them, and run a special gettext initialization somewhere before making use of the arrays or structs.

Note that we have marked the target texts. This is the necessary step to help xgettext to gather them.


Special Points for RNA

The rna files are linked as makesrna firstly, which will generate rna_*_gen.c. These are the real parts linked into blender. So we needn't do anything in rna_*.c except marking.

Mark strings with N_(). The commonest situations are:

...
/* EnumPropertyItem arrays, mostly show as options */
static EnumPropertyItem rotation_units[] = {
  {0, "DEGREES", 0, N_("Degrees"), N_("Use degrees for measuring rotation")},
  {USER_UNIT_ROT_RADIANS, "RADIANS", 0, N_("Radians"), ""},
  {0, NULL, 0, NULL, NULL}};
...
/* Property */
prop= RNA_def_property(srna, "use_separate", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_UNIT_OPT_SPLIT);
RNA_def_property_ui_text(prop, N_("Separate Units"), N_("Display units in pairs"));
RNA_def_property_update(prop, NC_WINDOW, NULL);

After first build, you can check the generated source files and find out which property list the texts belongs to, and add it to the rna_access.c:RNA_types_init_gettext()'s target struct array. Then the collection and translation will take place.

For Python Code

We have supplied blf.gettext(msgid) and blf.fake_gettext(msgid) which do the same things as _() and N_() in C code. Generally, functions can be called in most places in python, so you can just act like this:

from blf import gettext as _
...
label = -("String")

Make sure rename gettext as _, and fake_gettext as N_, or the xgettext cannot gather the texts.


So far, there is only one special case that we cannot apply _() to a python doc:

class A:
  '''doc'''

We'll handle it like:

class A:
  '''doc'''
  --doc-- = -('doc')

All these are true for add-on scripts, too.

Gather New Text Sources

Everytime you have marked the first string in a source file, add it to the /po/POTFILES.in, so that they can be gathered.

Then execute /po/update_pot.py, which will call the system's xgettext command. Checking the /po/blender.pot, you'll find those texts have been collected.

Add a New Language

If you want to add a new language, just add a new empty X.po under the /po, and run update_po.py, then you can edit the initialized X.po.


Next, make a folder at /release/bin/.blender/locale/X, run update_mo.po to compile the new PO file to a MO.


Then, edit the /source/blender/makesrna/intern/rna_userdef.c : rna_def_userdef_system(), add an item in the language_items array. This will be shown in the language selection menu.


At last, edit the /source/blender/blenfont/intern/blf_lang.c, add an item in the lang_to_locale array. This will set the real language when application starts.


- Done! Enjoy it.