Internationalisation
Table of Contents
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. Translation into other languages is highly appreciated. Please see:
Web2py localization engine
- Manual: https://web2py.com/book/default/chapter/04#T-and-Internationalization
- Tutorial: http://www.vimeo.com/7520812
- 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 web2py.py --timeout=120 ...
- suggest increasing the timeout from the default 10 minutes:
All Labels should be explicitly Internationalised:
table.field.label = T("Field")
To make dropdown options localisable, use this pattern:
module_field_type_opts = { 1:T("Option1"), 2:T("Option2"), 3:T("Option3") } 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, opt_module_field_type, ... )
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 manual). 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.
Time
All references to time should use request.utcnow
rather than request.now
ExtJS
"Put all texts to public class variables and then override them with translated versions."
e.g. in views/l10n.js