[Zope-Checkins] CVS: Zope3/lib/python/Zope/I18n - GlobalTranslationService.py:1.5

Barry Warsaw barry@wooz.org
Tue, 18 Jun 2002 14:21:18 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/I18n
In directory cvs.zope.org:/tmp/cvs-serv2370/lib/python/Zope/I18n

Modified Files:
	GlobalTranslationService.py 
Log Message:
Add "language fallbacks".  IOW, if no catalog for the requested
language can be found, provide for some fallback languages.  By
default, English is preferrable to the msgids (because they may be
explicit msgids), with msgids as the ultimate fallback.

setLanguageFallbacks(): Allow for zcml setting of different language
fallback order for the global translation service.  I'm not sure this
makes sense for ITranslationService so it's only in the
GlobalTranslationService for now.

translate(): if there is no catalog for the requested language, use
the designated fallbacks.  Note that this is only done on a
per-catalog basis; if a language catalog is found but that has no
translation for a particular msgid, tough luck.


=== Zope3/lib/python/Zope/I18n/GlobalTranslationService.py 1.4 => 1.5 ===
 from SimpleTranslationService import SimpleTranslationService
 
+# The configure.zcml file should specify a list of fallback languages for the
+# site.  If a particular catalog for a negotiated language is not available,
+# then the zcml specified order should be tried.  If that fails, then as a
+# last resort the languages in the following list are tried.  If these fail
+# too, then the msgid is returned.
+#
+# Note that these fallbacks are used only to find a catalog.  If a particular
+# message in a catalog is not translated, tough luck, you get the msgid.
+LANGUAGE_FALLBACKS = ['en']
+
 
 class GlobalTranslationService(SimpleTranslationService):
 
     __implements__ =  SimpleTranslationService.__implements__
 
-    def __init__(self, default_domain='global'):
+    def __init__(self, default_domain='global', fallbacks=None):
         # XXX We haven't specified that ITranslationServices have a default
         # domain.  So far, we've required the domain argument to .translate()
         self._domain = default_domain
@@ -32,6 +42,11 @@
         self._catalogs = {}
         # _data maps IMessageCatalog.getIdentifier() to IMessageCatalog
         self._data = {}
+        # What languages to fallback to, if there is no catalog for the
+        # requested language (no fallback on individual messages)
+        if fallbacks is None:
+            fallbacks = LANGUAGE_FALLBACKS
+        self._fallbacks = fallbacks
 
     def _registerMessageCatalog(self, language, domain, catalog_name):
         key = (language, domain)
@@ -44,6 +59,11 @@
                                      catalog.getDomain(),
                                      catalog.getIdentifier())
 
+    def setLanguageFallbacks(self, fallbacks=None):
+        if fallbacks is None:
+            fallbacks = LANGUAGE_FALLBACKS
+        self._fallbacks = fallbacks
+
 
     ############################################################
     # Implementation methods for interface
@@ -59,8 +79,16 @@
                 langs = [m[0] for m in self._catalogs.keys()]
                 target_language = negotiator.getLanguage(langs, context)
 
-        # Get the translation. Default is the msgid text itself.
-        catalog_names = self._catalogs.get((target_language, domain), [])
+        # Get the translation. Use the specified fallbacks if this fails
+        catalog_names = self._catalogs.get((target_language, domain))
+        if catalog_names is None:
+            for language in self._fallbacks:
+                catalog_names = self._catalogs.get((language, domain))
+                if catalog_names is not None:
+                    break
+        # Did the fallback fail?  Sigh, use the msgid
+        if catalog_names is None:
+            catalog_names = []
 
         text = msgid
         for name in catalog_names: