[Zope3-checkins] SVN: Zope3/trunk/ Made AbsoluteURL handle unicode names.

Bjorn Tillenius bjoti777 at student.liu.se
Thu Jun 3 01:10:47 EDT 2004


Log message for revision 25219:
Made AbsoluteURL handle unicode names.

__str__ and __call__ encode the name into UTF-8 and url quote it to
convert the name to ASCII. Also added __unicode__ to get a unicode
representation of the url.



-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2004-06-03 04:54:31 UTC (rev 25218)
+++ Zope3/trunk/doc/CHANGES.txt	2004-06-03 05:10:47 UTC (rev 25219)
@@ -32,6 +32,10 @@
       - The request's PATH_INFO variable is a unicode string now, so that
         the error service doesn't bail out when unicode urls are used.
 
+      - Made AbsoluteURL handle unicode names. __str__ and __call__ encode
+        the name into UTF-8 and url quote it to convert the name to ASCII.
+        Also added __unicode__ to get a unicode representation of the url.
+
     Restructuring
 
       - New api for getting sublocations and adapters for containers

Modified: Zope3/trunk/src/zope/app/traversing/browser/absoluteurl.py
===================================================================
--- Zope3/trunk/src/zope/app/traversing/browser/absoluteurl.py	2004-06-03 04:54:31 UTC (rev 25218)
+++ Zope3/trunk/src/zope/app/traversing/browser/absoluteurl.py	2004-06-03 05:10:47 UTC (rev 25219)
@@ -15,6 +15,7 @@
 
 $Id$
 """
+import urllib
 
 from zope.app.i18n import ZopeMessageIDFactory as _
 from zope.component import getViewProviding, getView
@@ -28,12 +29,17 @@
                        "This is probably due to a bug in setting up location "
                        "information.")
 
+_safe = '@+' # Characters that we don't want to have quoted
+
 def absoluteURL(ob, request):
     return str(getViewProviding(ob, IAbsoluteURL, request))
 
 class AbsoluteURL(BrowserView):
     implements(IAbsoluteURL)
 
+    def __unicode__(self):
+        return urllib.unquote(self.__str__()).decode('utf-8')
+
     def __str__(self):
         context = self.context
         request = self.request
@@ -54,7 +60,7 @@
             raise TypeError, _insufficientContext
 
         if name:
-            url += '/'+name
+            url += '/' + urllib.quote(name.encode('utf-8'), _safe)
 
         return url
 
@@ -81,7 +87,9 @@
 
         if name:
             base += ({'name': name,
-                      'url': ("%s/%s" % (base[-1]['url'], name))
+                      'url': ("%s/%s" % (base[-1]['url'],
+                                         urllib.quote(name.encode('utf-8'),
+                                                      _safe)))
                       }, )
 
         return base
@@ -89,6 +97,9 @@
 class SiteAbsoluteURL(BrowserView):
     implements(IAbsoluteURL)
 
+    def __unicode__(self):
+        return urllib.unquote(self.__str__()).decode('utf-8')
+
     def __str__(self):
         context = self.context
         request = self.request
@@ -99,7 +110,7 @@
         url = request.getApplicationURL()
         name = getattr(context, '__name__', None)
         if name:
-            url += '/'+name
+            url += '/' + urllib.quote(name.encode('utf-8'), _safe)
 
         return url
 
@@ -114,11 +125,12 @@
 
         base = ({'name':'', 'url': self.request.getApplicationURL()}, )
 
-
         name = getattr(context, '__name__', None)
         if name:
             base += ({'name': name,
-                      'url': ("%s/%s" % (base[-1]['url'], name))
+                      'url': ("%s/%s" % (base[-1]['url'],
+                                         urllib.quote(name.encode('utf-8'),
+                                                      _safe)))
                       }, )
 
         return base

Modified: Zope3/trunk/src/zope/app/traversing/browser/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/traversing/browser/interfaces.py	2004-06-03 04:54:31 UTC (rev 25218)
+++ Zope3/trunk/src/zope/app/traversing/browser/interfaces.py	2004-06-03 05:10:47 UTC (rev 25219)
@@ -19,20 +19,20 @@
 
 class IAbsoluteURL(Interface):
 
+    def __unicode__():
+        """Returns the URL as a unicode string."""
+
     def __str__():
-        """Get a human-readable string representation
-        """
+        """Returns an ASCII string with all unicode characters url quoted."""
 
     def __repr__():
-        """Get a string representation
-        """
+        """Get a string representation """
 
     def __call__():
-        """Get a string representation
-        """
+        """Returns an ASCII string with all unicode characters url quoted."""
 
     def breadcrumbs():
-        """Return a tuple like ({'name':name, 'url':url}, ...)
+        """Returns a tuple like ({'name':name, 'url':url}, ...)
 
         Name is the name to display for that segment of the breadcrumbs.
         URL is the link for that segment of the breadcrumbs.
@@ -41,5 +41,4 @@
 class IAbsoluteURLAPI(Interface):
 
     def absoluteURL(ob, request):
-        """Compute the absolute URL of an object
-        """
+        """Compute the absolute URL of an object """

Modified: Zope3/trunk/src/zope/app/traversing/browser/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/traversing/browser/tests.py	2004-06-03 04:54:31 UTC (rev 25218)
+++ Zope3/trunk/src/zope/app/traversing/browser/tests.py	2004-06-03 05:10:47 UTC (rev 25219)
@@ -25,6 +25,7 @@
 from zope.component import getService, getView
 from zope.i18n.interfaces import IUserPreferredCharsets
 from zope.interface import Interface, implements
+from zope.interface.verify import verifyObject
 from zope.publisher.browser import TestRequest
 from zope.publisher.http import IHTTPRequest, HTTPCharsets
 
@@ -49,6 +50,13 @@
         ztapi.provideAdapter(IHTTPRequest, IUserPreferredCharsets,
                              HTTPCharsets)
 
+    def test_interface(self):
+        request = TestRequest()
+        content = contained(TrivialContent(), Root(), name='a')
+        view = getView(content, 'absolute_url', request)
+        
+        verifyObject(IAbsoluteURL, view)
+
     def testBadObject(self):
         request = TestRequest()
         view = getView(42, 'absolute_url', request)
@@ -80,6 +88,38 @@
                           {'name': 'c', 'url': 'http://127.0.0.1/a/b/c'},
                           ))
 
+    def testBasicContext_unicode(self):
+        #Tests so that AbsoluteURL handle unicode names as well
+        request = TestRequest()
+        root = Root()
+        root.__name__ = u'\u0439'
+
+        content = contained(TrivialContent(), root, name=u'\u0442')
+        content = contained(TrivialContent(), content, name=u'\u0435')
+        content = contained(TrivialContent(), content, name=u'\u0441')
+        view = getView(content, 'absolute_url', request)
+        self.assertEqual(str(view),
+                         'http://127.0.0.1/%D0%B9/%D1%82/%D0%B5/%D1%81')
+        self.assertEqual(view(),
+                         'http://127.0.0.1/%D0%B9/%D1%82/%D0%B5/%D1%81')
+        self.assertEqual(unicode(view),
+                         u'http://127.0.0.1/\u0439/\u0442/\u0435/\u0441')
+        self.assertEqual(absoluteURL(content, request),
+                         'http://127.0.0.1/%D0%B9/%D1%82/%D0%B5/%D1%81')
+
+        breadcrumbs = view.breadcrumbs()
+        self.assertEqual(breadcrumbs,
+                         ({'name':  '', 'url': 'http://127.0.0.1'},
+                          {'name': u'\u0439', 'url': 'http://127.0.0.1/%D0%B9'},
+                          {'name': u'\u0442',
+                           'url': 'http://127.0.0.1/%D0%B9/%D1%82'},
+                          {'name': u'\u0435',
+                           'url': 'http://127.0.0.1/%D0%B9/%D1%82/%D0%B5'},
+                          {'name': u'\u0441',
+                           'url':
+                           'http://127.0.0.1/%D0%B9/%D1%82/%D0%B5/%D1%81'},
+                          ))
+
     def testRetainSkin(self):
         request = TestRequest()
         request._traversed_names = ('a', 'b')




More information about the Zope3-Checkins mailing list