[Zope-Checkins] CVS: Zope3/lib/python/Zope/TAL - DummyEngine.py:1.28.14.3.4.3

Barry Warsaw barry@wooz.org
Tue, 11 Jun 2002 15:28:38 -0400


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

Modified Files:
      Tag: fdrake-tal-i18n-branch
	DummyEngine.py 
Log Message:
Hook this stuff up to Stephan's translation service.  Note: it
won't work until I commit some changes to the new Zope3 trunk, but
those are outside the fdrake-tal-i18n-branch so they'll happen
separately.

Specific changes:

Import the ITranslationService and IDomain interfaces.

__init__(): create a DummyTranslationService instance and squirrel it
away on an instance attribute.

evaluate(): Evaluate 'path', 'var', 'global', and 'local' types by
calling a separate method instead of inlining.  This lets subclasses
override path or variable evaluation (useful for testing).

evaluatePathOrVar(): New method.

getTranslationService(): New method which returns the translation
service on the instance variable.

DummyDomain: New class which implements the IDomain interface.  This
knows how to split ${name} strings and uppercase everything except the
interpolation placeholders.  It also transforms ${name} into %(name)s
so we can use Python's built-in interpolation facilities.

DummyTranslationService: New class which implements the
ITranslationService interface, via the translate() and getDomain()
methods.


=== Zope3/lib/python/Zope/TAL/DummyEngine.py 1.28.14.3.4.2 => 1.28.14.3.4.3 ===
 
 from TALDefs import NAME_RE, TALESError, ErrorInfo
+from Zope.I18n.ITranslationService import ITranslationService
+from Zope.I18n.IDomain import IDomain
 
 Default = object()
 
@@ -39,6 +41,7 @@
         dict = {'nothing': None, 'default': Default}
         self.locals = self.globals = dict
         self.stack = [dict]
+        self.translationService = DummyTranslationService()
 
     def getCompilerError(self):
         return CompilerError
@@ -86,13 +89,7 @@
         if type in ("string", "str"):
             return expr
         if type in ("path", "var", "global", "local"):
-            expr = expr.strip()
-            if self.locals.has_key(expr):
-                return self.locals[expr]
-            elif self.globals.has_key(expr):
-                return self.globals[expr]
-            else:
-                raise TALESError("unknown variable: %s" % `expr`)
+            return self.evaluatePathOrVar(expr)
         if type == "not":
             return not self.evaluate(expr)
         if type == "exists":
@@ -104,6 +101,15 @@
                 raise TALESError("evaluation error in %s" % `expr`)
         raise TALESError("unrecognized expression: " + `expression`)
 
+    def evaluatePathOrVar(self, expr):
+        expr = expr.strip()
+        if self.locals.has_key(expr):
+            return self.locals[expr]
+        elif self.globals.has_key(expr):
+            return self.globals[expr]
+        else:
+            raise TALESError("unknown variable: %s" % `expr`)
+
     def evaluateValue(self, expr):
         return self.evaluate(expr)
 
@@ -173,6 +179,9 @@
     def getDefault(self):
         return Default
 
+    def getTranslationService(self):
+        return self.translationService
+
 class Iterator:
 
     def __init__(self, name, seq, engine):
@@ -190,3 +199,50 @@
         self.nextIndex = i+1
         self.engine.setLocal(self.name, item)
         return 1
+
+class DummyDomain:
+    __implements__ = IDomain
+
+    def translate(self, msgid, mapping=None, context=None,
+                  target_language=None):
+        # This is a fake translation service which simply uppercases non
+        # ${name} placeholder text in the message id.
+        #
+        # First, transform a string with ${name} placeholders into a list of
+        # substrings.  Then upcase everything but the placeholders, then glue
+        # things back together.
+        s = msgid.replace('%', '%%')
+        parts = re.split(r'(\${2})|\$([_a-z]\w*)|\${([_a-z]\w*)}',
+                         s, re.IGNORECASE)
+        if len(parts) == 1:
+            # There are no ${name} placeholders in the source string.  We use
+            # msgid here so we don't end up with doubled %'s.
+            return msgid.upper()
+        # Transform ${name} into %(name)s so we can use Python's built-in
+        # string interpolation feature.
+        xlateParts = []
+        for i in range(1, len(parts), 4):
+            if parts[i] is not None:
+                p = parts[i] = '$'
+            elif parts[i+1] is not None:
+                p = parts[i+1] = '%(' + parts[i+1] + ')s'
+            else:
+                p = parts[i+2] = '%(' + parts[i+2] + ')s'
+            xlateParts.append(p)
+            xlateParts.append(parts[i+3].upper())
+        if mapping is None:
+            mapping = {}
+        return ''.join(xlateParts) % mapping
+        
+
+class DummyTranslationService:
+    __implements__ = ITranslationService
+
+    def translate(self, domain, msgid, mapping=None, context=None,
+                  target_language=None):
+        # Ignore domain
+        return self.getDomain(domain).translate(msgid, mapping, context,
+                                                target_language)
+
+    def getDomain(self, domain):
+        return DummyDomain()