[Zope-Checkins]
SVN: Zope/branches/2.10/lib/python/Products/PageTemplates/
merge from trunk (PreferredResolver, more tests),
fixes Collector #2180
Andreas Jung
andreas at andreas-jung.com
Tue Jan 9 03:17:16 EST 2007
Log message for revision 71842:
merge from trunk (PreferredResolver, more tests), fixes Collector #2180
Changed:
U Zope/branches/2.10/lib/python/Products/PageTemplates/configure.zcml
U Zope/branches/2.10/lib/python/Products/PageTemplates/tests/testZopePageTemplate.py
U Zope/branches/2.10/lib/python/Products/PageTemplates/unicodeconflictresolver.py
-=-
Modified: Zope/branches/2.10/lib/python/Products/PageTemplates/configure.zcml
===================================================================
--- Zope/branches/2.10/lib/python/Products/PageTemplates/configure.zcml 2007-01-09 07:28:36 UTC (rev 71841)
+++ Zope/branches/2.10/lib/python/Products/PageTemplates/configure.zcml 2007-01-09 08:17:15 UTC (rev 71842)
@@ -2,7 +2,7 @@
<utility
provides="Products.PageTemplates.interfaces.IUnicodeEncodingConflictResolver"
- component="Products.PageTemplates.unicodeconflictresolver.DefaultUnicodeEncodingConflictResolver"
+ component="Products.PageTemplates.unicodeconflictresolver.PreferredCharsetResolver"
/>
</configure>
Modified: Zope/branches/2.10/lib/python/Products/PageTemplates/tests/testZopePageTemplate.py
===================================================================
--- Zope/branches/2.10/lib/python/Products/PageTemplates/tests/testZopePageTemplate.py 2007-01-09 07:28:36 UTC (rev 71841)
+++ Zope/branches/2.10/lib/python/Products/PageTemplates/tests/testZopePageTemplate.py 2007-01-09 08:17:15 UTC (rev 71842)
@@ -11,19 +11,25 @@
import unittest
import Zope2
import transaction
+
import zope.component.testing
-from zope.traversing.adapters import DefaultTraversable
+from zope.traversing.adapters import DefaultTraversable, Traverser
+from zope.publisher.http import HTTPCharsets
+
from Testing.makerequest import makerequest
from Testing.ZopeTestCase import ZopeTestCase, installProduct
from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate, manage_addPageTemplate
from Products.PageTemplates.utils import encodingFromXMLPreamble, charsetFromMetaEquiv
+from zope.component import provideUtility
+from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
+from Products.PageTemplates.unicodeconflictresolver import PreferredCharsetResolver
ascii_str = '<html><body>hello world</body></html>'
iso885915_str = '<html><body>üöäÜÖÄß</body></html>'
utf8_str = unicode(iso885915_str, 'iso-8859-15').encode('utf-8')
-xml_template = '''<?xml vesion="1.0" encoding="%s"?>
+xml_template = '''<?xml version="1.0" encoding="%s"?>
<foo>
üöäÜÖÄß
</foo>
@@ -76,8 +82,52 @@
self.assertEqual(extract('<html><META http-equiv="content-type" content="text/html; charset=iso-8859-15"></html>'), 'iso-8859-15')
self.assertEqual(extract('<html><META http-equiv="content-type" content="text/html"></html>'), None)
self.assertEqual(extract('<html>...<html>'), None)
-
+
+class ZPTUnicodeEncodingConflictResolution(ZopeTestCase):
+
+ def setUp(self):
+ super(ZPTUnicodeEncodingConflictResolution, self).setUp()
+ zope.component.provideAdapter(DefaultTraversable, (None,))
+ zope.component.provideAdapter(HTTPCharsets, (None,))
+ provideUtility(PreferredCharsetResolver, IUnicodeEncodingConflictResolver)
+ transaction.begin()
+
+ def tearDown(self):
+ transaction.abort()
+ self.app._p_jar.close()
+
+ def testISO_8859_15(self):
+ manage_addPageTemplate(self.app, 'test',
+ text='<div tal:content="python: request.get(\'data\')" />',
+ encoding='ascii')
+ zpt = self.app['test']
+ self.app.REQUEST.set('HTTP_ACCEPT_CHARSET', 'ISO-8859-15,utf-8')
+ self.app.REQUEST.set('data', 'üöä')
+ result = zpt.pt_render()
+ self.assertEqual(result.startswith(unicode('<div>üöä</div>', 'iso-8859-15')), True)
+
+ def testUTF8(self):
+ manage_addPageTemplate(self.app, 'test',
+ text='<div tal:content="python: request.get(\'data\')" />',
+ encoding='ascii')
+ zpt = self.app['test']
+ self.app.REQUEST.set('HTTP_ACCEPT_CHARSET', 'utf-8,ISO-8859-15')
+ self.app.REQUEST.set('data', unicode('üöä', 'iso-8859-15').encode('utf-8'))
+ result = zpt.pt_render()
+ self.assertEqual(result.startswith(unicode('<div>üöä</div>', 'iso-8859-15')), True)
+
+ def testUTF8WrongPreferredCharset(self):
+ manage_addPageTemplate(self.app, 'test',
+ text='<div tal:content="python: request.get(\'data\')" />',
+ encoding='ascii')
+ zpt = self.app['test']
+ self.app.REQUEST.set('HTTP_ACCEPT_CHARSET', 'iso-8859-15')
+ self.app.REQUEST.set('data', unicode('üöä', 'iso-8859-15').encode('utf-8'))
+ result = zpt.pt_render()
+ self.assertEqual(result.startswith(unicode('<div>üöä</div>', 'iso-8859-15')), False)
+
+
class ZopePageTemplateFileTests(ZopeTestCase):
def testPT_RenderWithAscii(self):
@@ -273,6 +323,7 @@
suite.addTests(unittest.makeSuite(ZPTUtilsTests))
suite.addTests(unittest.makeSuite(ZPTMacros))
suite.addTests(unittest.makeSuite(ZopePageTemplateFileTests))
+ suite.addTests(unittest.makeSuite(ZPTUnicodeEncodingConflictResolution))
return suite
if __name__ == '__main__':
Modified: Zope/branches/2.10/lib/python/Products/PageTemplates/unicodeconflictresolver.py
===================================================================
--- Zope/branches/2.10/lib/python/Products/PageTemplates/unicodeconflictresolver.py 2007-01-09 07:28:36 UTC (rev 71841)
+++ Zope/branches/2.10/lib/python/Products/PageTemplates/unicodeconflictresolver.py 2007-01-09 08:17:15 UTC (rev 71842)
@@ -12,7 +12,10 @@
##############################################################################
import sys
+
from zope.interface import implements
+from zope.i18n.interfaces import IUserPreferredCharsets
+
from Products.PageTemplates.interfaces import IUnicodeEncodingConflictResolver
default_encoding = sys.getdefaultencoding()
@@ -47,10 +50,47 @@
try:
return unicode(text)
except UnicodeDecodeError:
- encoding = getattr(context, 'managment_page_charset', default_encoding)
+ encoding = getattr(context, 'management_page_charset', default_encoding)
return unicode(text, encoding, self.mode)
+class PreferredCharsetResolver:
+ """ A resolver that tries use the encoding information
+ from the HTTP_ACCEPT_CHARSET header.
+ """
+ implements(IUnicodeEncodingConflictResolver)
+
+ def resolve(self, context, text, expression):
+
+ request = context.REQUEST
+
+ charsets = getattr(request, '__zpt_available_charsets', None)
+ if charsets is None:
+ charsets = IUserPreferredCharsets(request).getPreferredCharsets()
+
+ # add management_page_charset as one fallback
+ management_charset = getattr(context, 'management_page_charset', None)
+ if management_charset:
+ charsets.append(management_charset)
+
+ # add Python's default encoding as last fallback
+ charsets.append(default_encoding)
+
+ # cache list of charsets
+ request.__zpt_available_charsets = charsets
+
+ for enc in charsets:
+ if enc == '*': continue
+
+ try:
+ return unicode(text, enc)
+ except UnicodeDecodeError:
+ pass
+
+ return text
+
+
StrictUnicodeEncodingConflictResolver = Z2UnicodeEncodingConflictResolver('strict')
ReplacingUnicodeEncodingConflictResolver = Z2UnicodeEncodingConflictResolver('replace')
IgnoringUnicodeEncodingConflictResolver = Z2UnicodeEncodingConflictResolver('ignore')
+PreferredCharsetResolver = PreferredCharsetResolver()
More information about the Zope-Checkins
mailing list