Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

2 language applications

2 views
Skip to first unread message

Cristian Echeverria

unread,
Jun 5, 2001, 11:11:47 PM6/5/01
to
Hi

I have a gui application with all the messages in spanish, now I want to
include an option that allow the user to choose the language.

Wich is the right way to do things like this?
Any suggestion that can help me?

(I'am using Python2.0 and wxPython 2.3 on win9X)


Alex Martelli

unread,
Jun 6, 2001, 5:49:50 AM6/6/01
to
"Cristian Echeverria" <c...@tutopia.com> wrote in message
news:9fk6ll$4ln39$1...@ID-44371.news.dfncis.de...

See standard Python module gettext -- it's part of core
Python so you should have it in any distribution.

The tools to *generate* the needed messagefiles may or
may not be part of your Python distribution -- if you
can't find them, get a Python *source* distribution and
look for Tools/i18n. (Not sure why this VERY useful
directory is not included in some distributions - it's
just two Python scripts after all!-).

Say I have this big Python application saluta.py...:
print "buon giorno!"
print "ciao!")
print "buona sera!"

First I internationalize it as follows:
import os,gettext

os.environ.setdefault("LANGUAGE","it")
gettext.install('saluta')

print _("buon giorno!")
print _("ciao!")
print _("buona sera!")

The key thing is marking with _(...) the
strings which ARE to be translated!

Now I can't run it...:

D:\py21>python saluta.py
Traceback (most recent call last):
File "saluta.py", line 4, in ?
gettext.install('saluta')
File "d:\python21\lib\gettext.py", line 251, in install
translation(domain, localedir).install(unicode)
File "d:\python21\lib\gettext.py", line 238, in translation
raise IOError(ENOENT, 'No translation file found for domain', domain)
IOError: [Errno 2] No translation file found for domain: 'saluta'

D:\py21>

I have to prepare a message file first...:

D:\py21>python \python-2.1\Tools\i18n\pygettext.py saluta.py

D:\py21>type messages.pot
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: Wed Jun 06 11:29:12 2001\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <L...@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: ENCODING\n"
"Generated-By: pygettext.py 1.3\n"


#: saluta.py:5
msgid "buon giorno!"
msgstr ""

#: saluta.py:7
msgid "buona sera!"
msgstr ""

#: saluta.py:6
msgid "ciao!"
msgstr ""


D:\py21>

Now I have to edit this textfile to prepare the
needed .po files -- after the beginning metadata
(to be suitably edited), I'll have an it.po something
like:
#: saluta.py:5
msgid "buon giorno!"
msgstr "buon giorno!"

#: saluta.py:7
msgid "buona sera!"
msgstr "buona sera!"

#: saluta.py:6
msgid "ciao!"
msgstr "ciao!"

and an en.po something like:
#: saluta.py:5
msgid "buon giorno!"
msgstr "good morning!"

#: saluta.py:7
msgid "buona sera!"
msgstr "good evening!"

#: saluta.py:6
msgid "ciao!"
msgstr "hello!"

So I compile them:
D:\py21>python \python-2.1\Tools\i18n\msgfmt.py en.po

D:\py21>python \python-2.1\Tools\i18n\msgfmt.py it.po

And prepare the needed directories (lots of intermediate
mkdir's snipped:-):
D:\py21>mkdir \python21\share\locale\it\LC_MESSAGES
D:\py21>mkdir \python21\share\locale\en\LC_MESSAGES

and put the .mo files in the right places:

D:\py21>copy it.mo \python21\share\locale\it\LC_MESSAGES\saluta.mo
1 file(s) copied.

D:\py21>copy en.mo \python21\share\locale\en\LC_MESSAGES\saluta.mo
1 file(s) copied.

D:\py21>

And NOW it finally runs properly:

D:\py21>python saluta.py
buon giorno!
ciao!
buona sera!

D:\py21>set LANGUAGE=en

D:\py21>python saluta.py
good morning!
hello!
good evening!


I hope this simple toy example helps you get started... it's a
rich and complex system, meant to cover potentially very large
applications with dozens of languages, modules that must not
touch global settings, etc, etc, and it works quite smoothly
over its broad range of applicability, even though it MAY look
like a BIT of an overkill when just looking at one simple case
such as this one!-)


Alex

gods1child

unread,
Jun 6, 2001, 8:38:44 AM6/6/01
to
Why not just have two different dictionaries like:
en_messages = {'greetings':'Hello','farewell':'Goodbye','inquiry':'How
are you?'}
fr_messages = {'greetings':'Bonjour','farewell':'Au
revoir','inquiry':'Comment allez-vous?'}

then based on locale use the appropriate dictionary. To avoid
namespace pollution, and to avoid creating all the dictionaries when
all you need is one, you could create a class which could have
something like Java does:
MessageBundle.setLocale('en')
MessageBundle.get('greetings') # returns Hello
MessageBundle.setLocale('fr')
MessageBundle.get('greetings') # returns Bonjour

internally the class could use a dictionary created based on the
locale (instead of creating all of them and then assigning) if the
messages are few, or rely on a text file (with some caching mechanism)
for its data.

Cristian Echeverria

unread,
Jun 6, 2001, 9:29:27 AM6/6/01
to
That is what I call "AN EXPLANATION"...
...Thank you very much
Now I understand what are those .po and .mo files

Cristian


"Alex Martelli" <ale...@yahoo.com> wrote in message news:<9fkub...@enews2.newsguy.com>...

Alex Martelli

unread,
Jun 6, 2001, 10:02:51 AM6/6/01
to
"Cristian Echeverria" <c...@tutopia.com> wrote in message
news:33476bef.0106...@posting.google.com...

> That is what I call "AN EXPLANATION"...
> ...Thank you very much

You're welcome! I'm not good at concision, but I
_can_ be reasonably complete if I spend my energy
that way rather than trying for one-line summaries:-).

> Now I understand what are those .po and .mo files

Ah, you DO have some around already? Cool!


Alex

0 new messages