diff options
author | Malthe Borch <mborch@gmail.com> | 2012-10-10 09:25:17 +0000 |
---|---|---|
committer | Malthe Borch <mborch@gmail.com> | 2012-10-10 09:25:17 +0000 |
commit | 5a97e5eb26863c0338af9ef0a1646011ff59ba6c (patch) | |
tree | 08bb6ac1b2a259148e266dfe3b794986ffb60e45 /src/zope/i18n/translationdomain.py | |
parent | 1f8c08bee94884b6cd25465f74ceabc508bc0b21 (diff) | |
download | zope-i18n-5a97e5eb26863c0338af9ef0a1646011ff59ba6c.tar.gz |
The ZCML directive handler for a translation domain registration now
loads message catalogs lazily.
If the `zope_i18n_allowed_languages` environment variable is not
provided, the allowed languages are determined at runtime. To
participate in this, a translation domain implementation must now
expose a set of languages in a ``languages`` attribute.
The difficulty in this patch is that the ``INegotiator`` interface
relies on an "allowed languages" set, but this set is not readily
available. In the current definition of a translation domain, we can't
know until we attempt a translation whether a language is supported.
The solution in this patch is to require that a translation domain
exposes the defined languages and then query all translation domains
to determine the allowed languages. It would be nice if we could just
provide a value of ``None`` (meaning any language), but there's
already existing implementations that expect a set.
Diffstat (limited to 'src/zope/i18n/translationdomain.py')
-rw-r--r-- | src/zope/i18n/translationdomain.py | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/src/zope/i18n/translationdomain.py b/src/zope/i18n/translationdomain.py index dfc7f41..2faa301 100644 --- a/src/zope/i18n/translationdomain.py +++ b/src/zope/i18n/translationdomain.py @@ -17,7 +17,9 @@ import zope.component from zope.i18nmessageid import Message from zope.i18n import translate, interpolate from zope.i18n.simpletranslationdomain import SimpleTranslationDomain -from zope.i18n.interfaces import ITranslationDomain, INegotiator +from zope.i18n.interfaces import INegotiator +from zope.i18n.compile import compile_mo_file +from zope.i18n.gettextmessagecatalog import GettextMessageCatalog # The configuration should specify a list of fallback languages for the # site. If a particular catalog for a negotiated language is not available, @@ -31,6 +33,7 @@ LANGUAGE_FALLBACKS = ['en'] class TranslationDomain(SimpleTranslationDomain): + languages = () def __init__(self, domain, fallbacks=None): self.domain = domain @@ -43,22 +46,34 @@ class TranslationDomain(SimpleTranslationDomain): if fallbacks is None: fallbacks = LANGUAGE_FALLBACKS self._fallbacks = fallbacks + self._pending = {} + self.languages = set() def _registerMessageCatalog(self, language, catalog_name): key = language mc = self._catalogs.setdefault(key, []) mc.append(catalog_name) + self.languages.add(language) def addCatalog(self, catalog): self._data[catalog.getIdentifier()] = catalog self._registerMessageCatalog(catalog.language, catalog.getIdentifier()) + def addLanguage(self, lang, path): + self._pending.setdefault(lang, []).append(path) + self.languages.add(lang) + def setLanguageFallbacks(self, fallbacks=None): if fallbacks is None: fallbacks = LANGUAGE_FALLBACKS self._fallbacks = fallbacks + def importCatalog(self, lang, lc_messages_path): + path = compile_mo_file(self.domain, lc_messages_path) + catalog = GettextMessageCatalog(lang, self.domain, path) + self.addCatalog(catalog) + def translate(self, msgid, mapping=None, context=None, target_language=None, default=None): """See zope.i18n.interfaces.ITranslationDomain""" @@ -74,6 +89,10 @@ class TranslationDomain(SimpleTranslationDomain): # try to determine target language from negotiator utility target_language = negotiator.getLanguage(langs, context) + paths = self._pending.pop(target_language, ()) + for path in paths: + self.importCatalog(target_language, path) + return self._recursive_translate( msgid, mapping, target_language, default, context) @@ -124,7 +143,7 @@ class TranslationDomain(SimpleTranslationDomain): # this is a slight optimization for the case when there is a # single catalog. More importantly, it is extremely helpful # when testing and the test language is used, because it - # allows the test language to get the default. + # allows the test language to get the default. text = self._data[catalog_names[0]].queryMessage( msgid, default) else: |