[Zope3-checkins] CVS: Zope3/src/zope/tal - talgenerator.py:1.11
Fred L. Drake, Jr.
fred at zope.com
Thu Aug 14 14:23:52 EDT 2003
Update of /cvs-repository/Zope3/src/zope/tal
In directory cvs.zope.org:/tmp/cvs-serv6527
Modified Files:
talgenerator.py
Log Message:
Merge fixes from srichter-i18n-macro-interaction-branch:
- fix handling of nested translations with tal:content/replace and i18n:name
- port fix for #539 in collector from Zope 2.x (onerror)
- added relevant tests
- minor refactoring, added comments, and cleanup
Thanks go to Stephan Richter and Godefroid Chapelle for identifying
and fixing these corner cases.
=== Zope3/src/zope/tal/talgenerator.py 1.10 => 1.11 ===
--- Zope3/src/zope/tal/talgenerator.py:1.10 Fri Aug 8 19:04:56 2003
+++ Zope3/src/zope/tal/talgenerator.py Thu Aug 14 13:23:18 2003
@@ -278,7 +278,7 @@
else:
self.emit("setGlobal", name, cexpr)
- def emitOnError(self, name, onError):
+ def emitOnError(self, name, onError, TALtag, isend):
block = self.popProgram()
key, expr = parseSubstitution(onError)
cexpr = self.compileExpression(expr)
@@ -287,7 +287,10 @@
else:
assert key == "structure"
self.emit("insertStructure", cexpr, {}, [])
- self.emitEndTag(name)
+ if TALtag:
+ self.emitOptTag(name, (None, 1), isend)
+ else:
+ self.emitEndTag(name)
handler = self.popProgram()
self.emit("onError", block, handler)
@@ -316,7 +319,7 @@
assert key == "structure"
self.emit("insertStructure", cexpr, attrDict, program)
- def emitI18nVariable(self, varname, action, expression):
+ def emitI18nVariable(self, stuff):
# Used for i18n:name attributes. arg is extra information describing
# how the contents of the variable should get filled in, and it will
# either be a 1-tuple or a 2-tuple. If arg[0] is None, then the
@@ -329,6 +332,7 @@
# calculate the contents of the variable, e.g.
# "I live in <span i18n:name="country"
# tal:replace="here/countryOfOrigin" />"
+ varname, action, expression = stuff
m = _name_rx.match(varname)
if m is None or m.group() != varname:
raise TALError("illegal i18n:name: %r" % varname, self.position)
@@ -608,7 +612,11 @@
todo["scope"] = 1
if onError:
self.pushProgram() # handler
+ if TALtag:
+ self.pushProgram() # start
self.emitStartTag(name, list(attrlist)) # Must copy attrlist!
+ if TALtag:
+ self.pushProgram() # start
self.pushProgram() # block
todo["onError"] = onError
if define:
@@ -623,20 +631,25 @@
if repeatWhitespace:
self.emitText(repeatWhitespace)
if content:
- todo["content"] = content
- if replace:
+ if varname:
+ todo['i18nvar'] = (varname, I18N_CONTENT, None)
+ todo["content"] = content
+ self.pushProgram()
+ else:
+ todo["content"] = content
+ elif replace:
# tal:replace w/ i18n:name has slightly different semantics. What
# we're actually replacing then is the contents of the ${name}
# placeholder.
if varname:
- todo['i18nvar'] = (varname, replace)
+ todo['i18nvar'] = (varname, I18N_EXPRESSION, replace)
else:
todo["replace"] = replace
self.pushProgram()
# i18n:name w/o tal:replace uses the content as the interpolation
# dictionary values
elif varname:
- todo['i18nvar'] = (varname, None)
+ todo['i18nvar'] = (varname, I18N_REPLACE, None)
self.pushProgram()
if msgid is not None:
self.i18nLevel += 1
@@ -679,10 +692,12 @@
self.emitStartTag(name, self.replaceAttrs(attrlist, repldict), isend)
if optTag:
self.pushProgram()
- if content:
+ if content and not varname:
self.pushProgram()
if msgid is not None:
self.pushProgram()
+ if content and varname:
+ self.pushProgram()
if todo and position != (None, None):
todo["position"] = position
self.todoPush(todo)
@@ -727,10 +742,7 @@
# If there's no tal:content or tal:replace in the tag with the
# i18n:name, tal:replace is the default.
- i18nNameAction = I18N_REPLACE
if content:
- if varname:
- i18nNameAction = I18N_CONTENT
self.emitSubstitution(content, {})
# If we're looking at an implicit msgid, emit the insertTranslation
# opcode now, so that the end tag doesn't become part of the implicit
@@ -738,8 +750,12 @@
# the opcode after the i18nVariable opcode so we can better handle
# tags with both of them in them (and in the latter case, the contents
# would be thrown away for msgid purposes).
+ #
+ # Still, we should emit insertTranslation opcode before i18nVariable
+ # in case tal:content, i18n:translate and i18n:name in the same tag
if msgid is not None:
- if not varname:
+ if (not varname) or (
+ varname and (varname[1] == I18N_CONTENT)):
self.emitTranslation(msgid, i18ndata)
self.i18nLevel -= 1
if optTag:
@@ -758,26 +774,30 @@
if replace:
self.emitSubstitution(replace, repldict)
elif varname:
- if varname[1] is not None:
- i18nNameAction = I18N_EXPRESSION
# o varname[0] is the variable name
- # o i18nNameAction is either
+ # o varname[1] is either
# - I18N_REPLACE for implicit tal:replace
# - I18N_CONTENT for tal:content
# - I18N_EXPRESSION for explicit tal:replace
- # o varname[1] will be None for the first two actions and the
+ # o varname[2] will be None for the first two actions and the
# replacement tal expression for the third action.
- self.emitI18nVariable(varname[0], i18nNameAction, varname[1])
+ assert (varname[1]
+ in [I18N_REPLACE, I18N_CONTENT, I18N_EXPRESSION])
+ self.emitI18nVariable(varname)
# Do not test for "msgid is not None", i.e. we only want to test for
# explicit msgids here. See comment above.
- if msgid is not None and varname:
- self.emitTranslation(msgid, i18ndata)
+ if msgid is not None:
+ # in case tal:content, i18n:translate and i18n:name in the
+ # same tag insertTranslation opcode has already been
+ # emitted
+ if varname and (varname[1] <> I18N_CONTENT):
+ self.emitTranslation(msgid, i18ndata)
if repeat:
self.emitRepeat(repeat)
if condition:
self.emitCondition(condition)
if onError:
- self.emitOnError(name, onError)
+ self.emitOnError(name, onError, optTag and optTag[1], isend)
if scope:
self.emit("endScope")
if i18ncontext:
More information about the Zope3-Checkins
mailing list