Internationalize a Python application
(→Configure gettext Define the '_()' function) |
|||
(24 intermediate revisions not shown) | |||
Line 1: | Line 1: | ||
- | |||
- | |||
- | |||
- | |||
This page explains step by step how to add support for translations in a Python application for Maemo. | This page explains step by step how to add support for translations in a Python application for Maemo. | ||
- | There are already some [http://www.learningpython.com/2006/12/03/translating-your-pythonpygtk-application/ tutorials online] about how to internationalize (i18n) | + | There are already some [http://www.learningpython.com/2006/12/03/translating-your-pythonpygtk-application/ tutorials online] about how to internationalize (i18n) Python applications, but I find them difficult to follow and they lack some needed code and final tricks to make everything work fine. |
To support i18n we need to accomplish 5 tasks: | To support i18n we need to accomplish 5 tasks: | ||
- | # Define correctly a function '_()' that translates strings | + | # Define correctly a function '<code>_()</code>' that translates strings |
# Mark the strings in the code with that function | # Mark the strings in the code with that function | ||
# Generate a template for the translators | # Generate a template for the translators | ||
Line 16: | Line 12: | ||
== The overall process == | == The overall process == | ||
- | From the source code, using a command line tool, we will generate a ".pot" file. It is plain text file containing all strings that need translation in the project. This .pot file only needs to be generated/recreated when the strings change in the code (and | + | From the source code, using a command line tool, we will generate a "<code>.pot</code>" file. It is plain text file containing all strings that need translation in the project. This <code>.pot</code> file only needs to be generated/recreated when the strings change in the code (and ''not'' in every build!). There is only one <code>.pot</code> file per project. |
- | Then, from the .pot files and using another command line tool, we will generate the .po files for each language. There is one .po file per language, and it is the file that the translators need to complete. Both .pot and all .po files should be committed in the repository. | + | Then, from the <code>.pot</code> files and using another command line tool, we will generate the <code>.po</code> files for each language. There is one <code>.po</code> file per language, and it is the file that the translators need to complete. Both <code>.pot</code> and all <code>.po</code> files should be committed in the repository. |
- | But once your program is running, it doesn't use | + | But once your program is running, it doesn't use <code>.po</code> files directly, but a binary (compiled) version of them: the <code>.mo</code> files. These <code>.mo</code> files must be re-created on build time (when creating the package) and installed in the right location in the system. These are generated files, so don't commit them to the repository. |
From the code point of view, you just need to call few functions to tell gettext where are the translation files, what language do you want to use (usually the locale of the environment), and then it will use its implementation to find the right string. | From the code point of view, you just need to call few functions to tell gettext where are the translation files, what language do you want to use (usually the locale of the environment), and then it will use its implementation to find the right string. | ||
Ok, this is what we need to do. Let's code. | Ok, this is what we need to do. Let's code. | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
== Mark strings for i18n == | == Mark strings for i18n == | ||
- | This is one of the easiest parts. Browse the source code files that show something on the screen, and wrap the visible strings (window titles, dialog titles, notifications, labels, button labels and so on) with the '_()' function. | + | This is one of the easiest parts. Browse the source code files that show something on the screen, and wrap the visible strings (window titles, dialog titles, notifications, labels, button labels and so on) with the '<code>_()</code>' function. |
For example: | For example: | ||
Line 51: | Line 38: | ||
self.set_title ( _("All music") ) <------- ADD THIS! | self.set_title ( _("All music") ) <------- ADD THIS! | ||
</source> | </source> | ||
- | == | + | == How to add translations == |
- | + | Now you want to get a translation in an specific language. You need to generate a <code>.po</code> for it. | |
- | + | There are several ways to do it. I suggest to do it the easy way with poEdit: | |
+ | === With poEdit === | ||
+ | Poedit is cross-platform gettext catalogs (.po files) editor. For more information, see its website http://www.poedit.net/. | ||
+ | Just start it and generate a new catalog from the generated .pot file. | ||
+ | In the option window you can select the translated language, your name, email address and so on. This is useful, so others know who created this translation. | ||
- | + | Now you can start to translate all the text. If you modify your application and generate a new .pot file, you can easily import it. It will use all the existing translation and add the new/modified strings. If you changed the charset before like me, you will have to select it again. | |
+ | Every time you save the file, poEdit will generate a .mo file. You can use it for testing the new translation. | ||
- | + | === Manual way === | |
- | + | Go to the <code>po/</code> folder and run this command (again, inside/outside scratchbox doesn't matter): | |
- | == | + | |
- | + | ||
- | + | ||
- | + | ||
- | Go to the po/ folder and run this command (again, inside/outside scratchbox doesn't matter): | + | |
msginit --input=PROJECTNAME.pot --locale=LOCALE | msginit --input=PROJECTNAME.pot --locale=LOCALE | ||
- | For instance, if | + | For instance, if I want a <code>.po</code> file for the Spanish translation of my project Mussorgsky, I write: |
msginit --input=mussorgsky.pot --locale=es_ES | msginit --input=mussorgsky.pot --locale=es_ES | ||
- | It will generate a file "es.po" and translators can/must work on that file. | + | It will generate a file "<code>es.po</code>" and translators can/must work on that file. |
- | '''IMPORTANT''': by default the generated .po file declares its charset as ASCII. This means that translations with non-ascii characters will provoke an error in the program. To solve this, set the charset to 'utf-8': | + | '''IMPORTANT''': by default the generated <code>.po</code> file declares its charset as ASCII. This means that translations with non-ascii characters will provoke an error in the program. To solve this, set the charset to '<code>utf-8</code>': |
"Language-Team: Spanish\n" | "Language-Team: Spanish\n" | ||
Line 81: | Line 68: | ||
"Content-Type: text/plain; charset=utf-8\n" <--- THIS MUST BE UTF-8 | "Content-Type: text/plain; charset=utf-8\n" <--- THIS MUST BE UTF-8 | ||
- | If you don't know the locale of a language, can check [http://www.roseindia.net/tutorials/I18N/locales-list.shtml | + | If you don't know the locale of a language, can check [http://www.roseindia.net/tutorials/I18N/locales-list.shtml www.roseindia.net/tutorials/I18N/locales-list.shtml] or [http://people.w3.org/rishida/utils/subtags/ people.w3.org/rishida/utils/subtags]. |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + |
Latest revision as of 09:43, 4 May 2016
This page explains step by step how to add support for translations in a Python application for Maemo.
There are already some tutorials online about how to internationalize (i18n) Python applications, but I find them difficult to follow and they lack some needed code and final tricks to make everything work fine.
To support i18n we need to accomplish 5 tasks:
- Define correctly a function '
_()
' that translates strings - Mark the strings in the code with that function
- Generate a template for the translators
- Add translations
- Include the translations in the installation
Contents |
[edit] The overall process
From the source code, using a command line tool, we will generate a ".pot
" file. It is plain text file containing all strings that need translation in the project. This .pot
file only needs to be generated/recreated when the strings change in the code (and not in every build!). There is only one .pot
file per project.
Then, from the .pot
files and using another command line tool, we will generate the .po
files for each language. There is one .po
file per language, and it is the file that the translators need to complete. Both .pot
and all .po
files should be committed in the repository.
But once your program is running, it doesn't use .po
files directly, but a binary (compiled) version of them: the .mo
files. These .mo
files must be re-created on build time (when creating the package) and installed in the right location in the system. These are generated files, so don't commit them to the repository.
From the code point of view, you just need to call few functions to tell gettext where are the translation files, what language do you want to use (usually the locale of the environment), and then it will use its implementation to find the right string.
Ok, this is what we need to do. Let's code.
[edit] Mark strings for i18n
This is one of the easiest parts. Browse the source code files that show something on the screen, and wrap the visible strings (window titles, dialog titles, notifications, labels, button labels and so on) with the '_()
' function.
For example:
# import the _() function! import i18n _ = i18n.language.gettext class Example (hildon.StackableWindow): def __init__ (self): hildon.StackableWindow.__init__ (self) self.set_title ( _("All music") ) <------- ADD THIS!
[edit] How to add translations
Now you want to get a translation in an specific language. You need to generate a .po
for it.
There are several ways to do it. I suggest to do it the easy way with poEdit:
[edit] With poEdit
Poedit is cross-platform gettext catalogs (.po files) editor. For more information, see its website http://www.poedit.net/. Just start it and generate a new catalog from the generated .pot file. In the option window you can select the translated language, your name, email address and so on. This is useful, so others know who created this translation.
Now you can start to translate all the text. If you modify your application and generate a new .pot file, you can easily import it. It will use all the existing translation and add the new/modified strings. If you changed the charset before like me, you will have to select it again. Every time you save the file, poEdit will generate a .mo file. You can use it for testing the new translation.
[edit] Manual way
Go to the po/
folder and run this command (again, inside/outside scratchbox doesn't matter):
msginit --input=PROJECTNAME.pot --locale=LOCALE
For instance, if I want a .po
file for the Spanish translation of my project Mussorgsky, I write:
msginit --input=mussorgsky.pot --locale=es_ES
It will generate a file "es.po
" and translators can/must work on that file.
IMPORTANT: by default the generated .po
file declares its charset as ASCII. This means that translations with non-ascii characters will provoke an error in the program. To solve this, set the charset to 'utf-8
':
"Language-Team: Spanish\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" <--- THIS MUST BE UTF-8
If you don't know the locale of a language, can check www.roseindia.net/tutorials/I18N/locales-list.shtml or people.w3.org/rishida/utils/subtags.
- This page was last modified on 4 May 2016, at 09:43.
- This page has been accessed 62,524 times.