Commit 72c0de0c authored by Florent Guillaume's avatar Florent Guillaume

Merged changes from the Zope-2_6-branch:

Modified the translation service to return None if no translation exist.
So now using i18n tags without a translation service should give the
same behavior as before. The tests reflect that.
parent f2fc170b
......@@ -277,7 +277,9 @@ Zope Changes
- xmlrpclib has been updated to the Python 2.2 version, which includes
support for the Expat parser for unmarshalling data, which speeds up
things considerably.
- Added i18n support in TAL processing
Zope 2.6.0 alpha 1
Features Added
......
......@@ -13,14 +13,14 @@
##############################################################################
"""Global Translation Service for providing I18n to Page Templates.
$Id: GlobalTranslationService.py,v 1.2 2002/09/18 15:12:46 efge Exp $
$Id: GlobalTranslationService.py,v 1.3 2002/10/06 17:21:07 efge Exp $
"""
class DummyTranslationService:
"""Translation service that does nothing and returns the message id."""
"""Translation service that doesn't know anything about translation."""
def translate(self, domain, msgid, mapping=None,
context=None, target_language=None):
return msgid
return None
# XXX Not all of Zope.I18n.ITranslationService is implemented.
translationService = DummyTranslationService()
......
<html>
<body>
<head>
<p i18n:translate="foobar">baz</p>
<p i18n:domain="foo" i18n:translate="bar">baz</p>
<a href="foo" alt="alttext" i18n:attributes="alt">link</a>
<p i18n:domain="dom" i18n:translate="">
<span tal:replace="string:Lomax" i18n:name="name" /> was born in
<span tal:replace="string:Antarctica" i18n:name="country" />.
</p>
</head>
</body>
</html>
......@@ -2,6 +2,11 @@
<body>
<head>
<p i18n:domain="foo" i18n:translate="bar">baz</p>
<a href="foo" alt="alttext" i18n:attributes="alt">link</a>
<p i18n:domain="dom" i18n:translate="">
<span tal:replace="string:Lomax" i18n:name="name" /> was born in
<span tal:replace="string:Antarctica" i18n:name="country" />.
</p>
</head>
</body>
</html>
<html>
<body>
<head>
<p>foobar</p>
<p>baz</p>
<a href="foo" alt="alttext">link</a>
<p>
Lomax was born in
Antarctica.
</p>
</head>
</body>
</html>
......@@ -2,6 +2,8 @@
<body>
<head>
<p>[foo](bar)</p>
<a href="foo" alt="[default](alttext)">link</a>
<p>[dom](${name} was born in ${country}.)</p>
</head>
</body>
</html>
......@@ -47,6 +47,23 @@ def normalize(text):
return ' '.join(text.split())
NAME_RE = r"[a-zA-Z][a-zA-Z0-9_]*"
_interp_regex = re.compile(r'(?<!\$)(\$(?:%(n)s|{%(n)s}))' %({'n': NAME_RE}))
_get_var_regex = re.compile(r'%(n)s' %({'n': NAME_RE}))
def interpolate(text, mapping):
"""Interpolate ${keyword} substitutions."""
if not mapping:
return text
# Find all the spots we want to substitute.
to_replace = _interp_regex.findall(text)
# Now substitute with the variables in mapping.
for string in to_replace:
var = _get_var_regex.findall(string)[0]
text = text.replace(string, mapping.get(var))
return text
class AltTALGenerator(TALGenerator):
def __init__(self, repldict, expressionCompiler=None, xml=0):
......@@ -348,7 +365,11 @@ class TALInterpreter:
def i18n_attribute(self, s):
# s is the value of an attribute before translation
# it may have been computed
return self.translate(s, {})
xlated = self.translate(s, {})
if xlated is None:
return s
else:
return xlated
def no_tag(self, start, program):
state = self.saveState()
......@@ -518,25 +539,35 @@ class TALInterpreter:
# subnodes, which should /not/ go to the output stream.
tmpstream = self.StringIO()
self.interpretWithStream(stuff[1], tmpstream)
content = None
# We only care about the evaluated contents if we need an implicit
# message id. All other useful information will be in the i18ndict on
# the top of the i18nStack.
if msgid == '':
msgid = normalize(tmpstream.getvalue())
content = tmpstream.getvalue()
msgid = normalize(content)
self.i18nStack.pop()
# 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
# translations. OTOH, for implicit interpolation values, we don't
# want to escape stuff like ${name} <= "<b>Timmy</b>".
#s = escape(xlated_msgid)
s = xlated_msgid
# If there is no translation available, use evaluated content.
if xlated_msgid is None:
if content is None:
content = tmpstream.getvalue()
# We must do potential substitutions "by hand".
s = interpolate(content, i18ndict)
else:
# 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
# translations. OTOH, for implicit interpolation values, we don't
# want to escape stuff like ${name} <= "<b>Timmy</b>".
#s = escape(xlated_msgid)
s = xlated_msgid
# If there are i18n variables to interpolate into this string, better
# do it now.
# XXX efge: actually, this is already done by the translation service.
self._stream_write(s)
bytecode_handlers['insertTranslation'] = do_insertTranslation
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment