[Zope3-checkins] SVN: Zope3/trunk/ Fixed issue 301: Bug with
i18n:name and i18n:translate on the same element
Dmitry Vasiliev
dima at hlabs.spb.ru
Mon May 2 07:05:28 EDT 2005
Log message for revision 30226:
Fixed issue 301: Bug with i18n:name and i18n:translate on the same element
Changed:
U Zope3/trunk/doc/CHANGES.txt
U Zope3/trunk/src/zope/tal/talgenerator.py
U Zope3/trunk/src/zope/tal/tests/input/test22.html
U Zope3/trunk/src/zope/tal/tests/input/test28.html
U Zope3/trunk/src/zope/tal/tests/input/test31.html
U Zope3/trunk/src/zope/tal/tests/input/test36.html
U Zope3/trunk/src/zope/tal/tests/output/test29.html
U Zope3/trunk/src/zope/tal/tests/test_htmltalparser.py
U Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py
-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt 2005-05-02 10:53:40 UTC (rev 30225)
+++ Zope3/trunk/doc/CHANGES.txt 2005-05-02 11:05:28 UTC (rev 30226)
@@ -591,6 +591,9 @@
Bug Fixes
+ - Fixed issue #301: Bug with i18n:name and i18n:translate
+ on the same element
+
- The interface directive supports multiple interface types now.
- Fixed issue #314: i18n:translate removes line breaks
Modified: Zope3/trunk/src/zope/tal/talgenerator.py
===================================================================
--- Zope3/trunk/src/zope/tal/talgenerator.py 2005-05-02 10:53:40 UTC (rev 30225)
+++ Zope3/trunk/src/zope/tal/talgenerator.py 2005-05-02 11:05:28 UTC (rev 30226)
@@ -24,9 +24,8 @@
from zope.tal.taldefs import parseSubstitution
from zope.tal.translationcontext import TranslationContext, DEFAULT_DOMAIN
-I18N_REPLACE = 1
-I18N_CONTENT = 2
-I18N_EXPRESSION = 3
+I18N_CONTENT = 1
+I18N_EXPRESSION = 2
_name_rx = re.compile(NAME_RE)
@@ -330,20 +329,11 @@
raise TALError("illegal i18n:name: %r" % varname, self.position)
key = cexpr = None
program = self.popProgram()
- if action == I18N_REPLACE:
- # This is a tag with an i18n:name and a tal:replace (implicit or
- # explicit). Get rid of the first and last elements of the
- # program, which are the start and end tag opcodes of the tag.
- program = program[1:-1]
- elif action == I18N_CONTENT:
- # This is a tag with an i18n:name and a tal:content
- # (explicit-only). Keep the first and last elements of the
- # program, so we keep the start and end tag output.
- pass
- else:
- assert action == I18N_EXPRESSION
+ if action == I18N_EXPRESSION:
key, expr = parseSubstitution(expression)
cexpr = self.compileExpression(expr)
+ else:
+ assert action == I18N_CONTENT
self.emit('i18nVariable',
varname, program, cexpr, int(key == "structure"))
@@ -659,7 +649,7 @@
# i18n:name w/o tal:replace uses the content as the interpolation
# dictionary values
elif varname:
- todo['i18nvar'] = (varname, I18N_REPLACE, None)
+ todo['i18nvar'] = (varname, I18N_CONTENT, None)
self.pushProgram()
if msgid is not None:
self.i18nLevel += 1
@@ -793,16 +783,14 @@
elif varname:
# o varname[0] is the variable name
# o varname[1] is either
- # - I18N_REPLACE for implicit tal:replace
# - I18N_CONTENT for tal:content
# - I18N_EXPRESSION for explicit tal:replace
- # o varname[2] will be None for the first two actions and the
- # replacement tal expression for the third action. This
+ # o varname[2] will be None for the first action and the
+ # replacement tal expression for the second action. This
# can include a 'text' or 'structure' indicator.
- assert (varname[1]
- in [I18N_REPLACE, I18N_CONTENT, I18N_EXPRESSION])
+ assert (varname[1] in (I18N_CONTENT, I18N_EXPRESSION))
self.emitI18nVariable(varname)
- # Do not test for "msgid is not None", i.e. we only want to test for
+ # Do 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:
# in case tal:content, i18n:translate and i18n:name in the
Modified: Zope3/trunk/src/zope/tal/tests/input/test22.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test22.html 2005-05-02 10:53:40 UTC (rev 30225)
+++ Zope3/trunk/src/zope/tal/tests/input/test22.html 2005-05-02 11:05:28 UTC (rev 30226)
@@ -1,4 +1,4 @@
<span i18n:translate="">
- <span i18n:name="name"><b>Jim</b></span> was born in
- <span i18n:name="country">the USA</span>.
+ <span tal:omit-tag="" i18n:name="name"><b>Jim</b></span> was born in
+ <span tal:omit-tag="" i18n:name="country">the USA</span>.
</span>
Modified: Zope3/trunk/src/zope/tal/tests/input/test28.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test28.html 2005-05-02 10:53:40 UTC (rev 30225)
+++ Zope3/trunk/src/zope/tal/tests/input/test28.html 2005-05-02 11:05:28 UTC (rev 30226)
@@ -1,5 +1,5 @@
<p i18n:translate="verify">Your contact email address is recorded as
- <span i18n:name="email">
+ <span tal:omit-tag="" i18n:name="email">
<a href="mailto:user at example.com"
tal:content="request/submitter">user at host.com</a></span>
</p>
Modified: Zope3/trunk/src/zope/tal/tests/input/test31.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test31.html 2005-05-02 10:53:40 UTC (rev 30225)
+++ Zope3/trunk/src/zope/tal/tests/input/test31.html 2005-05-02 11:05:28 UTC (rev 30226)
@@ -1,5 +1,5 @@
<p i18n:translate="verify">Your contact email address is recorded as
-<span i18n:name="email">
+<span tal:omit-tag="" i18n:name="email">
<a href="user at host.com"
tal:attributes="href string:mailto:${request/submitter}"
tal:content="request/submitter">
Modified: Zope3/trunk/src/zope/tal/tests/input/test36.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/input/test36.html 2005-05-02 10:53:40 UTC (rev 30225)
+++ Zope3/trunk/src/zope/tal/tests/input/test36.html 2005-05-02 11:05:28 UTC (rev 30226)
@@ -2,5 +2,5 @@
<span i18n:translate="">
<span tal:replace="string:<foo>" i18n:name="name1" />
<span tal:replace="structure string:<bar />" i18n:name="name2" />
- <span i18n:name="name3"><b>some</b> <i>text</i></span>
+ <span tal:omit-tag="" i18n:name="name3"><b>some</b> <i>text</i></span>
</span>
Modified: Zope3/trunk/src/zope/tal/tests/output/test29.html
===================================================================
--- Zope3/trunk/src/zope/tal/tests/output/test29.html 2005-05-02 10:53:40 UTC (rev 30225)
+++ Zope3/trunk/src/zope/tal/tests/output/test29.html 2005-05-02 11:05:28 UTC (rev 30226)
@@ -1 +1 @@
-<div>AT THE TONE THE TIME WILL BE 59 MINUTES AFTER 6 PM... BEEP!</div>
+<div>AT THE TONE THE TIME WILL BE <span>59 minutes after 6 PM</span>... BEEP!</div>
Modified: Zope3/trunk/src/zope/tal/tests/test_htmltalparser.py
===================================================================
--- Zope3/trunk/src/zope/tal/tests/test_htmltalparser.py 2005-05-02 10:53:40 UTC (rev 30225)
+++ Zope3/trunk/src/zope/tal/tests/test_htmltalparser.py 2005-05-02 11:05:28 UTC (rev 30226)
@@ -693,29 +693,55 @@
# input/test22.html
self._run_check('''\
<span i18n:translate="">
- <span i18n:name="name"><b>Jim</b></span> was born in
- <span i18n:name="country">the USA</span>.
+ <span tal:omit-tag="" i18n:name="name"><b>Jim</b></span> was born in
+ <span tal:omit-tag="" i18n:name="country">the USA</span>.
</span>
-''', [
- ('setPosition', (1, 0)),
- ('beginScope', {'i18n:translate': ''}),
- ('startTag', ('span', [('i18n:translate', '', 'i18n')])),
- ('insertTranslation',
- ('',
- [('rawtextBeginScope', ('\n ', 2, (2, 2), 0, {'i18n:name': 'name'})),
- ('i18nVariable',
- ('name',
- [('rawtextOffset', ('<b>Jim</b>', 10))], None, 0)),
- ('rawtextBeginScope',
- (' was born in\n ', 2, (3, 2), 1, {'i18n:name': 'country'})),
- ('i18nVariable',
- ('country',
- [('rawtextOffset', ('the USA', 7))], None, 0)),
- ('endScope', ()),
- ('rawtextColumn', ('.\n', 0))])),
- ('endScope', ()),
- ('rawtextColumn', ('</span>\n', 0))
- ])
+''', [('setPosition', (1, 0)),
+ ('beginScope', {'i18n:translate': ''}),
+ ('startTag', ('span', [('i18n:translate', '', 'i18n')])),
+ ('insertTranslation',
+ ('',
+ [('rawtextBeginScope',
+ ('\n ', 2, (2, 2), 0, {'i18n:name': 'name', 'tal:omit-tag': ''})),
+ ('i18nVariable',
+ ('name',
+ [('optTag',
+ ('span',
+ '',
+ None,
+ 0,
+ [('startTag',
+ ('span',
+ [('tal:omit-tag', '', 'tal'),
+ ('i18n:name', 'name', 'i18n')]))],
+ [('rawtextOffset', ('<b>Jim</b>', 10))]))],
+ None,
+ 0)),
+ ('rawtextBeginScope',
+ (' was born in\n ',
+ 2,
+ (3, 2),
+ 1,
+ {'i18n:name': 'country', 'tal:omit-tag': ''})),
+ ('i18nVariable',
+ ('country',
+ [('optTag',
+ ('span',
+ '',
+ None,
+ 0,
+ [('startTag',
+ ('span',
+ [('tal:omit-tag', '', 'tal'),
+ ('i18n:name', 'country', 'i18n')]))],
+ [('rawtextOffset', ('the USA', 7))]))],
+ None,
+ 0)),
+ ('endScope', ()),
+ ('rawtextColumn', ('.\n', 0))])),
+ ('endScope', ()),
+ ('rawtextColumn', ('</span>\n', 0))
+ ])
def test_i18n_context_domain(self):
self._run_check("<span i18n:domain='mydomain'/>", [
@@ -804,8 +830,7 @@
<span i18n:data="here/currentTime"
i18n:translate="timefmt"
i18n:name="time">2:32 pm</span>... beep!</div>
-''',
-[('setPosition', (1, 0)),
+''', [('setPosition', (1, 0)),
('beginScope', {'i18n:translate': ''}),
('startTag', ('div', [('i18n:translate', '', 'i18n')])),
('insertTranslation',
@@ -818,100 +843,79 @@
{'i18n:data': 'here/currentTime',
'i18n:name': 'time',
'i18n:translate': 'timefmt'})),
- ('insertTranslation',
- ('timefmt',
+ ('i18nVariable',
+ ('time',
[('startTag',
('span',
[('i18n:data', 'here/currentTime', 'i18n'),
('i18n:translate', 'timefmt', 'i18n'),
('i18n:name', 'time', 'i18n')])),
- ('i18nVariable', ('time', [], None, 0))],
- '$here/currentTime$')),
+ ('insertTranslation',
+ ('timefmt',
+ [('rawtextOffset', ('2:32 pm', 7))],
+ '$here/currentTime$')),
+ ('rawtextOffset', ('</span>', 7))],
+ None,
+ 0)),
('endScope', ()),
('rawtextOffset', ('... beep!', 9))])),
('endScope', ()),
- ('rawtextColumn', ('</div>\n', 0))]
-)
+ ('rawtextColumn', ('</div>\n', 0))
+ ])
-
- def test_i18n_explicit_msgid_with_name(self):
- # input/test26.html
- self._run_check('''\
-<span i18n:translate="jobnum">
- Job #<span tal:replace="context/@@object_name"
- i18n:name="jobnum">NN</span></span>
-''', [
- ('setPosition', (1, 0)),
- ('beginScope', {'i18n:translate': 'jobnum'}),
- ('startTag', ('span', [('i18n:translate', 'jobnum', 'i18n')])),
- ('insertTranslation',
- ('jobnum',
- [('rawtextBeginScope',
- ('\n Job #',
- 9,
- (2, 9),
- 0,
- {'i18n:name': 'jobnum', 'tal:replace': 'context/@@object_name'})),
- ('i18nVariable',
- ('jobnum',
- [('startTag',
- ('span',
- [('tal:replace', 'context/@@object_name', 'tal'),
- ('i18n:name', 'jobnum', 'i18n')])),
- ('rawtextOffset', ('NN', 2)),
- ('rawtextOffset', ('</span>', 7))],
- '$context/@@object_name$',
- 0)),
- ('endScope', ())])),
- ('endScope', ()),
- ('rawtextColumn', ('</span>\n', 0))
- ])
-
def test_i18n_name_around_tal_content(self):
# input/test28.html
self._run_check('''\
<p i18n:translate="verify">Your contact email address is recorded as
- <span i18n:name="email">
+ <span tal:omit-tag="" i18n:name="email">
<a href="mailto:user at example.com"
tal:content="request/submitter">user at host.com</a></span>
</p>
-''', [
- ('setPosition', (1, 0)),
- ('beginScope', {'i18n:translate': 'verify'}),
- ('startTag', ('p', [('i18n:translate', 'verify', 'i18n')])),
- ('insertTranslation',
- ('verify',
- [('rawtextBeginScope',
- ('Your contact email address is recorded as\n ',
- 4,
- (2, 4),
- 0,
- {'i18n:name': 'email'})),
- ('i18nVariable',
- ('email',
- [('rawtextBeginScope',
- ('\n ',
- 4,
- (3, 4),
- 0,
- {'href': 'mailto:user at example.com',
- 'tal:content': 'request/submitter'})),
- ('startTag',
- ('a',
- [('href', 'href="mailto:user at example.com"'),
- ('tal:content', 'request/submitter', 'tal')])),
- ('insertText',
- ('$request/submitter$',
- [('rawtextOffset', ('user at host.com', 13))])),
- ('endScope', ()),
- ('rawtextOffset', ('</a>', 4))],
- None,
- 0)),
- ('endScope', ()),
- ('rawtextColumn', ('\n', 0))])),
- ('endScope', ()),
- ('rawtextColumn', ('</p>\n', 0))
- ])
+''', [('setPosition', (1, 0)),
+ ('beginScope', {'i18n:translate': 'verify'}),
+ ('startTag', ('p', [('i18n:translate', 'verify', 'i18n')])),
+ ('insertTranslation',
+ ('verify',
+ [('rawtextBeginScope',
+ ('Your contact email address is recorded as\n ',
+ 4,
+ (2, 4),
+ 0,
+ {'i18n:name': 'email', 'tal:omit-tag': ''})),
+ ('i18nVariable',
+ ('email',
+ [('optTag',
+ ('span',
+ '',
+ None,
+ 0,
+ [('startTag',
+ ('span',
+ [('tal:omit-tag', '', 'tal'),
+ ('i18n:name', 'email', 'i18n')]))],
+ [('rawtextBeginScope',
+ ('\n ',
+ 4,
+ (3, 4),
+ 0,
+ {'href': 'mailto:user at example.com',
+ 'tal:content': 'request/submitter'})),
+ ('startTag',
+ ('a',
+ [('href', 'href="mailto:user at example.com"'),
+ ('tal:content', 'request/submitter', 'tal')])),
+ ('insertText',
+ ('$request/submitter$',
+ [('rawtextOffset', ('user at host.com', 13))])),
+ ('endScope', ()),
+ ('rawtextOffset', ('</a>', 4))]))],
+ None,
+ 0)),
+ ('endScope', ()),
+ ('rawtextColumn', ('\n', 0))])),
+ ('endScope', ()),
+ ('rawtextColumn', ('</p>\n', 0))
+ ])
def test_i18n_name_with_tal_content(self):
# input/test27.html
Modified: Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py
===================================================================
--- Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py 2005-05-02 10:53:40 UTC (rev 30225)
+++ Zope3/trunk/src/zope/tal/tests/test_talinterpreter.py 2005-05-02 11:05:28 UTC (rev 30226)
@@ -195,7 +195,7 @@
def test_complex_replace_with_messageid_and_i18nname(self):
program, macros = self._compile(
'<div i18n:translate="" >'
- '<em i18n:name="foo_name">'
+ '<em tal:omit-tag="" i18n:name="foo_name">'
'<span tal:replace="foo"/>'
'</em>'
'</div>')
@@ -267,7 +267,7 @@
def translate(self, msgid, mapping=None,
context=None, target_language=None, default=None):
- self.data.append(msgid)
+ self.data.append((msgid, mapping))
return DummyTranslationDomain.translate(
self,
msgid, mapping, context, target_language, default)
@@ -286,13 +286,38 @@
self.interpreter = TALInterpreter(program, {}, self.engine,
stream=result)
self.interpreter()
- self.assert_('BaRvAlUe' in xlatdmn.data)
- self.assert_('This is text for ${bar_name}.' in
- xlatdmn.data)
+ msgids = list(xlatdmn.data)
+ msgids.sort()
+ self.assertEqual(2, len(msgids))
+ self.assertEqual('BaRvAlUe', msgids[0][0])
+ self.assertEqual('This is text for ${bar_name}.', msgids[1][0])
+ self.assertEqual({'bar_name': '<span>BARVALUE</span>'}, msgids[1][1])
self.assertEqual(
'<div>THIS IS TEXT FOR <span>BARVALUE</span>.</div>\n',
result.getvalue())
+ def test_i18ntranslate_i18nname_and_attributes(self):
+ # Test for Issue 301: Bug with i18n:name and i18n:translate
+ # on the same element
+ xlatdmn = self._getCollectingTranslationDomain()
+ result = StringIO()
+ program, macros = self._compile(
+ '<p i18n:translate="">'
+ 'Some static text and a <a tal:attributes="href string:url"'
+ ' i18n:name="link" i18n:translate="">link text</a>.</p>')
+ self.interpreter = TALInterpreter(program, {}, self.engine,
+ stream=result)
+ self.interpreter()
+ msgids = list(xlatdmn.data)
+ msgids.sort()
+ self.assertEqual(2, len(msgids))
+ self.assertEqual('Some static text and a ${link}.', msgids[0][0])
+ self.assertEqual({'link': '<a href="url">LINK TEXT</a>'}, msgids[0][1])
+ self.assertEqual('link text', msgids[1][0])
+ self.assertEqual(
+ '<p>SOME STATIC TEXT AND A <a href="url">LINK TEXT</a>.</p>\n',
+ result.getvalue())
+
def test_for_raw_msgids(self):
# Test for Issue 314: i18n:translate removes line breaks from
# <pre>...</pre> contents
@@ -307,9 +332,11 @@
self.interpreter = TALInterpreter(program, {}, self.engine,
stream=result)
self.interpreter()
- self.assert_('This is text for div.' in xlatdmn.data)
- self.assert_(' This is text\n <b>\tfor</b>\n pre. ' in
- xlatdmn.data)
+ msgids = list(xlatdmn.data)
+ msgids.sort()
+ self.assertEqual(2, len(msgids))
+ self.assertEqual(' This is text\n <b>\tfor</b>\n pre. ', msgids[0][0])
+ self.assertEqual('This is text for div.', msgids[1][0])
self.assertEqual(
'<div>THIS IS TEXT FOR DIV.</div>'
'<pre> THIS IS TEXT\n <B>\tFOR</B>\n PRE. </pre>\n',
@@ -328,8 +355,10 @@
self.interpreter = TALInterpreter(program, {}, self.engine,
stream=result)
self.interpreter()
- self.assert_('This is text <b> for</b> barvalue.' in
- xlatdmn.data)
+ msgids = list(xlatdmn.data)
+ msgids.sort()
+ self.assertEqual(1, len(msgids))
+ self.assertEqual('This is text <b> for</b> barvalue.', msgids[0][0])
self.assertEqual(
'<?xml version="1.0"?>\n'
'<pre>THIS IS TEXT <B> FOR</B> BARVALUE.</pre>\n',
More information about the Zope3-Checkins
mailing list