Gettext: Difference between revisions
Crazy-chris (talk | contribs) (initial edit) |
|||
(3 intermediate revisions by 2 users not shown) | |||
Line 7: | Line 7: | ||
== in Python == |
== in Python == |
||
To load the gettext function and alias it to _, include this code |
To load the gettext function and alias it to _, include this code: |
||
⚫ | |||
# 1. Import Gettext |
|||
⚫ | |||
⚫ | |||
# 2. Set Application Infos |
|||
gettext.bindtextdomain('PROJECT_NAME', '/ROJECT_DIR') |
|||
gettext.textdomain('PROJECT_NAME') |
|||
⚫ | |||
# 3. Alias gettext.gettext to _ |
|||
_ = gettext.gettext |
|||
Now you're set for using gettext in your project. Simply wrap outputs from 'Output' to _('Output'). Keep in mind, that not only strings can require [http://en.wikipedia.org/wiki/Internationalization localization], but also |
Now you're set for using gettext in your project. Simply wrap outputs from 'Output' to _('Output'). Keep in mind, that not only strings can require [http://en.wikipedia.org/wiki/Internationalization localization], but also |
||
Line 28: | Line 20: | ||
== Example Application == |
== Example Application == |
||
Let's make up an example (test.py) for translating names and titles: |
Let's make up an example (test.py) for translating names and titles: |
||
import gettext |
from gettext import gettext as _ |
||
gettext.bindtextdomain('hello_world', '/home/hello/world') |
|||
gettext.textdomain('hello_world') |
|||
_ = gettext.gettext |
|||
title = _('Mr.') |
title = _('Mr.') |
||
Line 37: | Line 26: | ||
firstname = 'Chris' |
firstname = 'Chris' |
||
name = _('%title %lastname %firstname') |
name = _('%(title)s %(lastname)s %(firstname)s') % {'title': title, 'lastname': lastname, 'firstname': firstname}; |
||
print name; |
|||
== Comments == |
== Comments == |
||
It's possible to leave a comment directed to the translator like this: |
It's possible to leave a comment directed to the translator like this: |
||
# TRANSLATORS: Please |
# TRANSLATORS: Please just rearrange the 3 '%(...)s' parts as required. |
||
name = _('%title %lastname %firstname') |
name = _('%(title)s %(lastname)s %(firstname)s') % {'title': title, 'lastname': lastname, 'firstname': firstname}; |
||
Note: When './setup.py genpot' is used in a sugar environment to generate the PO template file, |
|||
it specifies 'TRANS:' rather than 'TRANSLATORS:' as the marker for comments to translators. |
|||
So, if the software being internationalized is a python sugar activity, comments directed to the |
|||
translators should be marked with 'TRANS:' rather than 'TRANSLATORS:'. |
|||
== Building the template file == |
== Building the template file == |
||
Line 48: | Line 43: | ||
xgettext --add-comments=TRANSLATORS: test.py |
xgettext --add-comments=TRANSLATORS: test.py |
||
Our newly created template file with translations (eg. messages.po) looks like this: |
Our newly created template file with translations (eg. messages.po) looks like this: |
||
#: test.py: |
#: test.py:3 |
||
msgid "Mr." |
msgid "Mr." |
||
msgstr "" |
msgstr "" |
||
⚫ | |||
# |
# TRANSLATORS: Please just rearrange the 3 '%(...)s' parts as required. |
||
#: test.py: |
#: test.py:7 |
||
#, python-format |
|||
msgid "%title %lastname %firstname" |
msgid "%(title)s %(lastname)s %(firstname)s" |
||
msgstr "" |
msgstr "" |
||
Distribute it and people can start translating. |
Distribute it and people can start translating. |
||
Line 63: | Line 59: | ||
This will create a file named 'de.po'. The translator needs to edit it either by hand or with tools such as [http://en.wikipedia.org/wiki/PoEdit poEdit]. When they are done, it will could like this: |
This will create a file named 'de.po'. The translator needs to edit it either by hand or with tools such as [http://en.wikipedia.org/wiki/PoEdit poEdit]. When they are done, it will could like this: |
||
#: test.py: |
#: test.py:4 |
||
msgid "Mr." |
msgid "Mr." |
||
msgstr "Hr." |
msgstr "Hr." |
||
⚫ | |||
#: test.py: |
#: test.py:9 |
||
#, python-format |
|||
msgid "%title %lastname %firstname" |
|||
msgid "%(title)s %(lastname)s %(firstname)s" |
|||
msgstr "%(title)s %(firstname)s %(lastname)s" |
|||
Finally, the .po files are compiled into a binary .mo file with ''msgfmt''. |
Finally, the .po files are compiled into a binary .mo file with ''msgfmt''. |
Latest revision as of 23:43, 5 January 2009
gettext is the GNU internationalization (i18n) library. It is commonly used for writing multilingual programs. The latest version is 0.17.
Programming
Source code is first modified to use the GNU gettext calls. This is, for most programming languages, done by wrapping strings that the user will see in the gettext function. To save on typing time, and to reduce code clutter, this function is commonly aliased to _, so that the Python code
print 'Hello World!'
would become
print _('Hello World!')
in Python
To load the gettext function and alias it to _, include this code:
from gettext import gettext as _
Now you're set for using gettext in your project. Simply wrap outputs from 'Output' to _('Output'). Keep in mind, that not only strings can require localization, but also
- numbers,
- time formats,
- currencies,
- time zones,
- names and titles,
- ...
Example Application
Let's make up an example (test.py) for translating names and titles:
from gettext import gettext as _ title = _('Mr.') lastname = 'Hager' firstname = 'Chris' name = _('%(title)s %(lastname)s %(firstname)s') % {'title': title, 'lastname': lastname, 'firstname': firstname}; print name;
Comments
It's possible to leave a comment directed to the translator like this:
# TRANSLATORS: Please just rearrange the 3 '%(...)s' parts as required. name = _('%(title)s %(lastname)s %(firstname)s') % {'title': title, 'lastname': lastname, 'firstname': firstname};
Note: When './setup.py genpot' is used in a sugar environment to generate the PO template file, it specifies 'TRANS:' rather than 'TRANSLATORS:' as the marker for comments to translators. So, if the software being internationalized is a python sugar activity, comments directed to the translators should be marked with 'TRANS:' rather than 'TRANSLATORS:'.
Building the template file
No we use xgettext to build a .po template file from the source code. This will be used by translators to derive local .po files.
xgettext --add-comments=TRANSLATORS: test.py
Our newly created template file with translations (eg. messages.po) looks like this:
#: test.py:3 msgid "Mr." msgstr "" # TRANSLATORS: Please just rearrange the 3 '%(...)s' parts as required. #: test.py:7 #, python-format msgid "%(title)s %(lastname)s %(firstname)s" msgstr ""
Distribute it and people can start translating.
Translating
We can derive a local .po file from the template using the msginit program. For a german translation we'd do this:
msginit --locale=de --input=messages.po
This will create a file named 'de.po'. The translator needs to edit it either by hand or with tools such as poEdit. When they are done, it will could like this:
#: test.py:4 msgid "Mr." msgstr "Hr." #: test.py:9 #, python-format msgid "%(title)s %(lastname)s %(firstname)s" msgstr "%(title)s %(firstname)s %(lastname)s"
Finally, the .po files are compiled into a binary .mo file with msgfmt.
msgfmt de.po
These are now ready for distribution with the software package.
Running
On Unix-type systems, the user sets the environment variable LC_MESSAGES, and the program will display strings in the selected language, if there is an .mo file for it.