Version 16 (modified by Fran Boon, 12 years ago) ( diff )



The original language of the Sahana Eden user interface, source code labels and comments, and the Wiki pages is English (international). No contributions can be accepted without being at least translated to english. If you need help to translate your contents to english, please contact the Sahana Localization team.

However, translation to other languages is highly appreciated - please contact the Localization team for advice.

Translation to a new language

Create language file:

Web2py localization engine

  • Tutorial:
  • T() function performs dictionary lookups (similar to GNU/gettext _()), see here for example
    • Convenience function: Use Tstr() for non web2py python modules that aren't aware of T()
  • the dictionaries are located in the languages subfolder of the application
  • dictionaries can be translated using the web2py web interface (RAD mode)
    • suggest increasing the timeout from the default 10 minutes: python --timeout=120 ...

All Labels should be explicitly Internationalised:

table.field.label = T("Field")

To make dropdown options localisable, use this pattern:

module_field_type_opts = {
opt_module_field_type = SQLTable(None, "opt_module_field_type",
                    Field("field_type", "integer', notnull=True,
                    requires = IS_IN_SET(module_field_type_opts),
                    default = 1,
                    represent = lambda opt: opt and module_field_type_opts[opt]))

table = db.define_table(tablename,

All reference to the options in View code should be by Index not by string (since the string can be changed).

The first problem for i18n are variables in the translation strings. While
constants are recognized and added to the translation file during code
compilation - variable strings are not added to the translation file unless
you execute the code with all possible combinations:

"If the string to be translated is not a constant but a variable, it will be
added to the translation file at runtime to be translated later." (web2py

This is problematic, because you need to know which functions have to be
executed and how in order to produce a complete dictionary, and at every code
update, you have to do it again. Hence, it is likely that those strings will
be missed by offline translations (i.e. pre-deployment), and have to be
translated in the field. As an exception, this is acceptable.

The other problem is that your construction assumes that number of words and
word order in the respective phrases are the same in all languages, which is
a typical idea of English native speakers - but not true. Especially we
Germans use a quite different word order (which is totally twisted, as you
know, but we're not the only ones), e.g.

'Add New ' + table_name

must be German one of:
table_name + " erstellen" (best option)
table_name + " hinzufügen" (still ok)
"Füge " + table_name + " hinzu" (imperative form, not good in German)

where translating the "New" would introduce another problem which is about the
grammatical gender:
"New X" could be in German either of "Neue X", "Neues X" oder "Neuen X". And
believe me not even I can explain the German use of gender (e.g. "Software"
is female, i.e. "she" - and this is not even a German word; while a computer
is male, i.e. "he", and that is not a German word either).

And semantics make it yet harder. It might be possible to "Bearbeite
Mitteilung" ("Edit Message"), which means to "modify the contents of a
message", while it is not possible to "Bearbeite Person" ("Edit Person"),
because that would mean to "make that person agree in something".

Similar for "Löschen" (for "Delete"), which is pretty ambiguous as it stands
for "Delete" (remove something from the computer memory) as well as
for "Extinguish" (e.g. fire) and some other meanings. To use it
with "Person", you'd need to use an object periphrasis like "Eintrag"
("entry") or "Personendaten" ("personal data").

Difficult, difficult. Therefore - use string constants.


All references to time should use request.utcnow rather than

Pootle/translate toolkit and web2py dictionaries

Wiki pages translation

  • translated pages with ISO 639-2 language code extension (original english page = no extension), e.g.
    • original page:
    • german translation:
  • insert [[TranslatedPages]] macro to display a list of available translations of a page (at best at bottom of page)



Note: See TracWiki for help on using the wiki.