I have a first stab at an i18n/l10n version of a plugin using my smallest plugin,
SmartEject.
First, I went through and wrapped all the UI strings in _(). Then, taking what I found in calibre/utils/localization.py as inspiration, I added a l10n.py file containing:
Code:
try:
from calibre.utils.localization import get_lang
mofile = get_resources("l10n/messages_%s.mo"%get_lang())
import cStringIO
from gettext import GNUTranslations
trans = GNUTranslations(cStringIO.StringIO(mofile))
def gettext(x):
return trans.gettext(x)
except Exception, e:
def gettext(x):
return x
Then in my plugin code files I added:
Code:
from calibre_plugins.smarteject.l10n import gettext as _
First, I:
- used pygettext.py to generate a messages.pot file from my source .py files,
- copied that to l10n/messages_en.po,
- edited that with Poedit to add "(en)" a few places for proof it worked,
- created .mo file and
- included l10n/messages_en.mo in the plugin zip file.
That version of SmartEject is
posted here.
I will not be in the least surprised if I've over looked any number of additional details, but it's starting point.
Issues I've identified with this process so far:
- In an ideal world (for plugin in writers anyway), the functionality in l10n.py would be part of the plugin base classes and plugins would just use _() and provide .mo files in a standard directory in the plugin zip.
- Should the plugin name itself in the InterfaceAction and InterfaceActionBase child classes be localized? What happens to users with the plugin already installed if it changes?
- What's the best practice for maintaining the .po files? How do you update existing .po translations to add new UI strings?
- Are/Should translated versions of the plugin forums exist somewhere? Like the plugin index page?