[Zope-Checkins] CVS: Zope3/lib/python/Zope/TAL - TALInterpreter.py:1.63.10.3.4.7

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


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

Modified Files:
      Tag: fdrake-tal-i18n-branch
	TALInterpreter.py 
Log Message:
Support for i18n:data attribute.  Specific changes:

do_insertTranslation(): If an expression was included in the
insertTranslation opcode, it's the expression given by the i18n:data
attribute.  Evaluate it here and pass the resulting object to the
translate() method on the TALInterpreter.

translate(): If the i18n:data object is given, it should be a
dictionary which will be update()'d into the i18ndict (XXX this
interface may change).  Then get the translation service from the
engine and call the ITranslationService.translate() method to do the
actual translation.

Before we do this though, check the (new) i18nInterpolate flag which
usually true, but can be set to false for debugging and testing.


=== Zope3/lib/python/Zope/TAL/TALInterpreter.py 1.63.10.3.4.6 => 1.63.10.3.4.7 ===
             # i18n interpolation dictionary.
             value = self.engine.evaluate(stuff[1])
+        # Either the i18n:name tag is nested inside an i18n:translate in which
+        # case the last item on the stack has the i18n dictionary and string
+        # representation, or the i18n:name and i18n:translate attributes are
+        # in the same tag, in which case the i18nStack will be empty.  In that
+        # case we can just output the ${name} to the stream
         i18ndict, srepr = self.i18nStack[-1]
         i18ndict[varname] = value
         placeholder = '${%s}' % varname
@@ -492,6 +497,7 @@
     def do_insertTranslation(self, stuff):
         i18ndict = {}
         srepr = []
+        obj = None
         self.i18nStack.append((i18ndict, srepr))
         msgid = stuff[0]
         if msgid == '':
@@ -506,7 +512,10 @@
             # internal whitespace to a single space.
             msgid = ' '.join(msgid.split())
         self.i18nStack.pop()
-        xlated_msgid = self.translate(msgid, i18ndict)
+        # See if there is was an i18n:data for msgid
+        if len(stuff) > 2:
+            obj = self.engine.evaluate(stuff[2])
+        xlated_msgid = self.translate(msgid, i18ndict, obj)
         # XXX I can't decide whether we want to cgi escape the translated
         # string or not.  OT1H not doing this could introduce a cross-site
         # scripting vector by allowing translators to sneak JavaScript into
@@ -570,34 +579,18 @@
             self.interpret(block)
     bytecode_handlers["loop"] = do_loop
 
-    def translate(self, msgid, i18ndict=None):
-        # XXX: need to fill this in with TranslationService calls.  For now,
+    def translate(self, msgid, i18ndict=None, obj=None):
+        # XXX is this right?
+        if obj:
+            i18ndict.update(obj)
+        # XXX need to fill this in with TranslationService calls.  For now,
         # we'll just do simple interpolation based on a $-strings to %-strings
         # algorithm in Mailman.
         if not self.i18nInterpolate:
             return msgid
-        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 i18ndict is None:
-            i18ndict = {}
-        return ''.join(xlateParts) % i18ndict
+        service = self.engine.getTranslationService()
+        # We need to pass in one of context or target_language
+        return service.translate(self.i18nContext.domain, msgid, i18ndict)
 
     def do_rawtextColumn(self, (s, col)):
         self._stream_write(s)