Index: /qPingTool/branches/plone-3.1/PingTool.py
===================================================================
--- /qPingTool/branches/plone-3.1/PingTool.py	(revision 185)
+++ /qPingTool/branches/plone-3.1/PingTool.py	(revision 186)
@@ -3,9 +3,9 @@
 from Acquisition import aq_base
 
-from zope.interface import implements
 from AccessControl import ClassSecurityInfo
 
 from Products.Archetypes.public import *
 
+from Products.CMFCore.ActionProviderBase import ActionProviderBase
 from Products.CMFPlone.interfaces.OrderedContainer import IOrderedContainer
 from Products.CMFPlone.PloneFolder import PloneFolder
@@ -15,5 +15,4 @@
 from Products.CMFCore.permissions import ManagePortal
 from Products.CMFCore.utils import getToolByName
-from Products.CMFCore.ActionProviderBase import ActionProviderBase
 
 from Products.ATContentTypes.content.folder import ATFolder
@@ -21,7 +20,6 @@
 from Products.XMLRPCMethod.XMLRPCMethod import RPCThread, XMLRPCMethod
 
-from util import getCanonicalURL
 from zLOG import LOG
-from config import TOOL_ID, PROJECTNAME
+from config import PROJECTNAME
 
 _marker = []
@@ -49,49 +47,24 @@
         ) + ATFolder.manage_options
 
-    security.declareProtected(ManagePortal, 'manage_overview')
-    manage_overview = PageTemplateFile(os.path.join('www','overview'), globals())
-    manage_overview.__name__ = 'manage_overview'
-    manage_overview._need__name__ = 0
-
-    def om_icons(self):
-        """ Checking on ZMI for canonical_url setting."""
-        icons = ({'path':'misc_/qPingTool/tool.gif' \
-                    ,'alt':self.meta_type \
-                    ,'title':self.meta_type \
-                },)
-        if not getCanonicalURL(self):
-            icons = icons + ({'path':'misc_/PageTemplates/exclamation.gif' \
-                                ,'alt':'Error' \
-                                ,'title':'PingTool needs setting canonical_url' \
-                                },)
-        return icons
-
     security.declareProtected(ManagePortal, 'pingFeedReader')
     def pingFeedReader(self,context):
         """ ping """
-        status = 'success'
-        message = 'The servers are pinged'
-        if context.meta_type == 'BlogFolder':
-    	    blog = context.simpleblog_tool.getFrontPage(context)
+        status = 'failed'
+        if context.meta_type == 'WeblogEntry':
+    	    blog = context.getWeblog()
     	else:
     	    blog = context
 
-        title = blog.Title()
-        portal = context.portal_url.getPortalObject()
-        canonical_url = getCanonicalURL(context)
-        if canonical_url:
-            url = context.portal_url.getRelativeContentURL(blog)
-            url = canonical_url + url
-        else:
-            return status, 'Ping is impossible.See portal_pingtool.'
+        pingProp = self.getPingProperties(blog)
+    	if not pingProp['enable_ping']:
+    	    message = 'Ping is dissabled.'
+    	    return status, message
 
+        url = blog.absolute_url_path()[1:]
     	ps = getToolByName(context,'portal_syndication')
     	rss_templates = {'Blog':'','RSS1':'/RSS','RSS2':'/RSS2'}
-        pingProp = self.getPingProperties(blog)
-    	result = 'ok'
-    	if not pingProp['enable_ping']:
-    	   message = 'Ping is dissabled'
-    	   return status, message
     	if ps.isSyndicationAllowed(blog):
+            status = 'success'
+            message = 'The servers are pinged.'
 	    sites = pingProp['ping_sites']
 	    if sites:
@@ -104,10 +77,15 @@
                     PingMethod = XMLRPCMethod('myid',"",site_url,site_method,25)
                     blog_url = url + site_rss_version
+                    title = blog.Title()
                     try: 
                         #LOG('qPing', 0, title, blog_url, site_url)
-                        result = PingMethod(title,blog_url)
+                        result_ping = PoingMethod(title,blog_url)
+                        result = result_ping['message']
                     except:
-			LOG('qPingTool', 100,"The site "+  site_url+" generated error for "+ blog_url, result)
-                    message += '\n'+ str(result)
+                        result = 'The site %s generated error for %s.' % (site_url, blog_url)
+			LOG('qPingTool', 100, result)
+                    message += '\nReturned message: ' + str(result)
+        else:
+            message = 'The %s is not syndication allowed' % url 
         return status, message
 
Index: ingTool/branches/plone-3.1/adapter.py
===================================================================
--- /qPingTool/branches/plone-3.1/adapter.py	(revision 185)
+++ 	(revision )
@@ -1,67 +1,0 @@
-from zope.interface import Interface, implements #, Attribute
-from zope.component import adapts
-
-from Products.CMFPlone.interfaces import IPloneBaseTool
-from Products.CMFCore.utils import getToolByName
-
-class ICanonicalURL(Interface):
-    """ Interface for canonical URL API providing."""
-
-    def getCanonicalURL():
-        """Get canonical_url property value."""
-
-    #def setCanonicalURL():
-        #"""Set canonical_url property value."""
-
-    #def addCanonicalURL(value):
-        #"""Add canonical_url property value"""
-
-    #def hasCanonicalURL():
-        #"""Check if portal has canonical_url property"""
-
-
-class CanonicalURL(object):
-    """ CanonicalURL adapter
-    """
-    adapts(IPloneBaseTool)
-    implements(ICanonicalURL)
-
-    def __init__(self, context):
-        """ init
-        """
-        self.context = context
-
-    def getCanonicalURL(self):
-        """Get canonical_url property value
-        """
-        portal = getToolByName(self.context, 'portal_url').getPortalObject()
-        return portal.getProperty('canonical_url',None)
-
-    #def setCanonicalURL(self, value):
-        #"""Update canonical_url property value
-        #"""
-        #portal = getToolByName(self, 'portal_url').getPortalObject()
-        #portal.manage_changeProperties(canonical_url=str(value))
-
-
-    #def addCanonicalURL(self, value):
-        #"""Add canonical_url property value
-        #"""
-        #portal = getToolByName(self, 'portal_url').getPortalObject()
-        #if not portal.hasProperty('canonical_url'):
-            #portal.manage_delProperties(ids=['canonical_url'])
-        #portal.manage_addProperty('canonical_url', str(value), 'string')
-
-
-    #def hasCanonicalURL(self):
-        #"""Check if portal has canonical_url property
-        #"""
-        #portal = getToolByName(self, 'portal_url').getPortalObject()
-        #return portal.hasProperty('canonical_url')
-
-# Register adapter
-
-#def registerAdapter():
-#    from Products.CMFPlone.interfaces import IPloneBaseTool
-#    from zope.component import provideAdapter
-#    provideAdapter(CanonicalURL, adapts=[IPloneBaseTool,], provides=ICanonicalURL )
Index: /qPingTool/branches/plone-3.1/configure.zcml
===================================================================
--- /qPingTool/branches/plone-3.1/configure.zcml	(revision 185)
+++ /qPingTool/branches/plone-3.1/configure.zcml	(revision 186)
@@ -4,6 +4,4 @@
     i18n_domain="qPingTool">
 
-   <adapter factory=".adapter.CanonicalURL" />
-
    <include file="profiles.zcml" />
    <include file="skins.zcml" />
Index: ingTool/branches/plone-3.1/profiles/default/archetype_tool.xml
===================================================================
--- /qPingTool/branches/plone-3.1/profiles/default/archetype_tool.xml	(revision 185)
+++ 	(revision )
@@ -1,11 +1,0 @@
-<?xml version="1.0"?>
-<archetypetool>
- <catalogmap>
-  <type portal_type="PingTool">
-   <catalog value="portal_catalog"/>
-  </type>
-  <type portal_type="PingInfo">
-   <catalog value="portal_catalog"/>
-  </type>
- </catalogmap>
-</archetypetool>
Index: ingTool/branches/plone-3.1/profiles/default/factorytool.xml
===================================================================
--- /qPingTool/branches/plone-3.1/profiles/default/factorytool.xml	(revision 185)
+++ 	(revision )
@@ -1,7 +1,0 @@
-<?xml version="1.0"?>
-<object name="portal_factory" meta_type="Plone Factory Tool">
- <factorytypes>
-  <type portal_type="PingInfo"/>
-  <type portal_type="PingTool"/>
- </factorytypes>
-</object>
Index: /qPingTool/branches/plone-3.1/profiles/default/types/PingInfo.xml
===================================================================
--- /qPingTool/branches/plone-3.1/profiles/default/types/PingInfo.xml	(revision 185)
+++ /qPingTool/branches/plone-3.1/profiles/default/types/PingInfo.xml	(revision 186)
@@ -17,4 +17,11 @@
  <property name="allowed_content_types"/>
  <property name="allow_discussion">False</property>
+
+ <alias from="(Default)" to="base_view"/>
+ <alias from="edit" to="base_edit"/>
+ <alias from="index.html" to="(Default)"/>
+ <alias from="properties" to="base_metadata"/>
+ <alias from="view" to="base_view"/>
+
  <action title="View"
          action_id="view"
@@ -33,5 +40,5 @@
          visible="True"
          i18n:attributes="title">
-  <permission value="View"/>
+  <permission value="Modify portal content"/>
  </action>
  <action title="Properties"
Index: /qPingTool/branches/plone-3.1/profiles/default/types/PingTool.xml
===================================================================
--- /qPingTool/branches/plone-3.1/profiles/default/types/PingTool.xml	(revision 185)
+++ /qPingTool/branches/plone-3.1/profiles/default/types/PingTool.xml	(revision 186)
@@ -13,19 +13,36 @@
  <property name="filter_content_types">True</property>
  <property name="allowed_content_types">
-  <element value="PingInfo"/></property>
+  <element value="PingInfo"/>
+ </property>
  <property name="allow_discussion">False</property>
+ <property name="default_view">base_view</property>
+ <property name="view_methods">
+  <element value="base_view"/>
+ </property>
+ <property name="default_view_fallback">False</property>
+
  <alias from="(Default)" to="base_view"/>
  <alias from="edit" to="base_edit"/>
  <alias from="index.html" to="(Default)"/>
- <alias from="properties" to="base_metadata"/>
  <alias from="view" to="(Default)"/>
+
  <action title="View"
          action_id="view"
          category="object"
          condition_expr=""
-         url_expr="string:folder_contents"
+         url_expr="string:${object_url}/view"
          visible="True"
          i18n:attributes="title">
   <permission value="Manage portal"/>
  </action>
+ <action title="Edit"
+         action_id="edit"
+         category="object"
+         condition_expr=""
+         url_expr="string:${object_url}/edit"
+         visible="True"
+         i18n:attributes="title">
+  <permission value="Modify portal content"/>
+ </action>
+
 </object>
Index: /qPingTool/branches/plone-3.1/tests/__init__.py
===================================================================
--- /qPingTool/branches/plone-3.1/tests/__init__.py	(revision 186)
+++ /qPingTool/branches/plone-3.1/tests/__init__.py	(revision 186)
@@ -0,0 +1,6 @@
+"""\
+qPingTool tests package
+
+To run all tests type 'python runalltests.py'
+"""
+
Index: /qPingTool/branches/plone-3.1/tests/base.py
===================================================================
--- /qPingTool/branches/plone-3.1/tests/base.py	(revision 186)
+++ /qPingTool/branches/plone-3.1/tests/base.py	(revision 186)
@@ -0,0 +1,15 @@
+from Products.PloneTestCase import PloneTestCase as PloneTestCase
+
+from Products.CMFCore.utils import getToolByName
+from Products.qPingTool import PingTool
+from Products.qPingTool.config import *
+
+PRODUCTS = ['qPingTool', 'Quills']
+
+map(PloneTestCase.installProduct, ('qPingTool', 'XMLRPCMethod', 'Quills'))
+
+PloneTestCase.setupPloneSite(products=PRODUCTS)
+
+class TestCase(PloneTestCase.PloneTestCase):
+    """Base class used for test cases
+    """
Index: /qPingTool/branches/plone-3.1/tests/framework.py
===================================================================
--- /qPingTool/branches/plone-3.1/tests/framework.py	(revision 186)
+++ /qPingTool/branches/plone-3.1/tests/framework.py	(revision 186)
@@ -0,0 +1,106 @@
+##############################################################################
+#
+# ZopeTestCase
+#
+# COPY THIS FILE TO YOUR 'tests' DIRECTORY.
+#
+# This version of framework.py will use the SOFTWARE_HOME
+# environment variable to locate Zope and the Testing package.
+#
+# If the tests are run in an INSTANCE_HOME installation of Zope,
+# Products.__path__ and sys.path with be adjusted to include the
+# instance's Products and lib/python directories respectively.
+#
+# If you explicitly set INSTANCE_HOME prior to running the tests,
+# auto-detection is disabled and the specified path will be used
+# instead.
+#
+# If the 'tests' directory contains a custom_zodb.py file, INSTANCE_HOME
+# will be adjusted to use it.
+#
+# If you set the ZEO_INSTANCE_HOME environment variable a ZEO setup
+# is assumed, and you can attach to a running ZEO server (via the
+# instance's custom_zodb.py).
+#
+##############################################################################
+#
+# The following code should be at the top of every test module:
+#
+# import os, sys
+# if __name__ == '__main__':
+#     execfile(os.path.join(sys.path[0], 'framework.py'))
+#
+# ...and the following at the bottom:
+#
+# if __name__ == '__main__':
+#     framework()
+#
+##############################################################################
+
+__version__ = '0.2.3'
+
+# Save start state
+#
+__SOFTWARE_HOME = os.environ.get('SOFTWARE_HOME', '')
+__INSTANCE_HOME = os.environ.get('INSTANCE_HOME', '')
+
+if __SOFTWARE_HOME.endswith(os.sep):
+    __SOFTWARE_HOME = os.path.dirname(__SOFTWARE_HOME)
+
+if __INSTANCE_HOME.endswith(os.sep):
+    __INSTANCE_HOME = os.path.dirname(__INSTANCE_HOME)
+
+# Find and import the Testing package
+#
+if not sys.modules.has_key('Testing'):
+    p0 = sys.path[0]
+    if p0 and __name__ == '__main__':
+        os.chdir(p0)
+        p0 = ''
+    s = __SOFTWARE_HOME
+    p = d = s and s or os.getcwd()
+    while d:
+        if os.path.isdir(os.path.join(p, 'Testing')):
+            zope_home = os.path.dirname(os.path.dirname(p))
+            sys.path[:1] = [p0, p, zope_home]
+            break
+        p, d = s and ('','') or os.path.split(p)
+    else:
+        print 'Unable to locate Testing package.',
+        print 'You might need to set SOFTWARE_HOME.'
+        sys.exit(1)
+
+import Testing, unittest
+execfile(os.path.join(os.path.dirname(Testing.__file__), 'common.py'))
+
+# Include ZopeTestCase support
+#
+if 1:   # Create a new scope
+
+    p = os.path.join(os.path.dirname(Testing.__file__), 'ZopeTestCase')
+
+    if not os.path.isdir(p):
+        print 'Unable to locate ZopeTestCase package.',
+        print 'You might need to install ZopeTestCase.'
+        sys.exit(1)
+
+    ztc_common = 'ztc_common.py'
+    ztc_common_global = os.path.join(p, ztc_common)
+
+    f = 0
+    if os.path.exists(ztc_common_global):
+        execfile(ztc_common_global)
+        f = 1
+    if os.path.exists(ztc_common):
+        execfile(ztc_common)
+        f = 1
+
+    if not f:
+        print 'Unable to locate %s.' % ztc_common
+        sys.exit(1)
+
+# Debug
+#
+print 'SOFTWARE_HOME: %s' % os.environ.get('SOFTWARE_HOME', 'Not set')
+print 'INSTANCE_HOME: %s' % os.environ.get('INSTANCE_HOME', 'Not set')
+sys.stdout.flush()
Index: /qPingTool/branches/plone-3.1/tests/runalltests.py
===================================================================
--- /qPingTool/branches/plone-3.1/tests/runalltests.py	(revision 186)
+++ /qPingTool/branches/plone-3.1/tests/runalltests.py	(revision 186)
@@ -0,0 +1,28 @@
+#
+# Runs all tests in the current directory
+#
+# Execute like:
+#   python runalltests.py
+#
+# Alternatively use the testrunner:
+#   python /path/to/Zope/utilities/testrunner.py -qa
+#
+
+import os, sys
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+import unittest
+TestRunner = unittest.TextTestRunner
+suite = unittest.TestSuite()
+
+tests = os.listdir(os.curdir)
+tests = [n[:-3] for n in tests if n.startswith('test') and n.endswith('.py')]
+
+for test in tests:
+    m = __import__(test)
+    if hasattr(m, 'test_suite'):
+        suite.addTest(m.test_suite())
+
+if __name__ == '__main__':
+    TestRunner().run(suite)
Index: /qPingTool/branches/plone-3.1/tests/testRegister.py
===================================================================
--- /qPingTool/branches/plone-3.1/tests/testRegister.py	(revision 186)
+++ /qPingTool/branches/plone-3.1/tests/testRegister.py	(revision 186)
@@ -0,0 +1,32 @@
+#
+# Register skins
+#
+
+import os, sys
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from base import *
+
+class TestSetup(TestCase):
+
+    def afterSetUp(self):
+        self.loginAsPortalOwner()
+
+    def testRegisterSkins(self):
+        test_content = ['ping_setup', 'ping_now', 'save_ping_setup', 'tool.gif']
+        self.failUnless(not getattr(self.portal.portal_skins, 'qpingtool', None)==None)
+        content = [i.id for i in self.portal.portal_skins.qpingtool.objectValues()]
+        content.sort()
+        test_content.sort()
+        self.failUnless(content==test_content)
+
+
+def test_suite():
+    from unittest import TestSuite, makeSuite
+    suite = TestSuite()
+    suite.addTest(makeSuite(TestSetup))
+    return suite
+
+if __name__ == '__main__':
+    framework()
Index: /qPingTool/branches/plone-3.1/tests/testSkeleton.py
===================================================================
--- /qPingTool/branches/plone-3.1/tests/testSkeleton.py	(revision 186)
+++ /qPingTool/branches/plone-3.1/tests/testSkeleton.py	(revision 186)
@@ -0,0 +1,25 @@
+#
+# qPingTool TestCase
+#
+
+import os, sys
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from Testing import ZopeTestCase
+
+ZopeTestCase.installProduct('qPingTool')
+
+class TestSomething(ZopeTestCase.ZopeTestCase):
+
+    def afterSetUp(self):
+        pass
+
+def test_suite():
+    from unittest import TestSuite, makeSuite
+    suite = TestSuite()
+    suite.addTest(makeSuite(TestSomething))
+    return suite
+
+if __name__ == '__main__':
+    framework()
Index: /qPingTool/branches/plone-3.1/tests/test_pinginfo.py
===================================================================
--- /qPingTool/branches/plone-3.1/tests/test_pinginfo.py	(revision 186)
+++ /qPingTool/branches/plone-3.1/tests/test_pinginfo.py	(revision 186)
@@ -0,0 +1,36 @@
+#
+# PingInfo TestCase
+#
+
+import os, sys
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from base import *
+
+class TestPingInfo(TestCase):
+
+    def afterSetUp(self):
+        self.loginAsPortalOwner()
+        self.portal.invokeFactory('PingInfo', id='pi1',title='Ping Info 1')
+        self.pi1 = getattr(self.portal, 'pi1', None)
+
+    def testAddedPingInfo(self):
+        self.pi1.setUrl('http://nohost')
+        self.failUnlessEqual(self.pi1.getUrl(), 'http://nohost')
+        self.failUnlessEqual(self.pi1.getMethod_name(), 'weblogUpdates.ping')
+        self.pi1.setMethod_name('testmethod')
+        self.failUnlessEqual(self.pi1.getMethod_name(), 'testmethod')        
+        self.pi1.setRss_version(self.pi1.Vocabulary('rss_version')[0][-1])
+        self.failUnlessEqual(self.pi1.getRss_version(), 'RSS2')
+
+
+def test_suite():
+    from unittest import TestSuite, makeSuite
+    suite = TestSuite()
+    suite.addTest(makeSuite(TestPingInfo))
+    return suite
+
+if __name__ == '__main__':
+    framework()
+
Index: /qPingTool/branches/plone-3.1/tests/test_pingtool.py
===================================================================
--- /qPingTool/branches/plone-3.1/tests/test_pingtool.py	(revision 186)
+++ /qPingTool/branches/plone-3.1/tests/test_pingtool.py	(revision 186)
@@ -0,0 +1,84 @@
+#
+# PingTool TestCase
+#
+
+import os, sys
+if __name__ == '__main__':
+    execfile(os.path.join(sys.path[0], 'framework.py'))
+
+from base import *
+
+class TestPingTool(TestCase):
+
+    def afterSetUp(self):
+        self.loginAsPortalOwner()
+        self.ptool = self.portal._getOb(TOOL_ID)
+        self.portal.invokeFactory('Weblog', id='b1',title='Blog 1')
+        self.b1 = getattr(self.portal, 'b1', None)
+        self.b1.enableSyndication()
+
+    def testPingToolType(self):
+        self.failUnless(self.ptool.meta_type==PingTool.PingTool.meta_type)
+
+    def testSetupPing(self):
+        obj = self.b1
+
+        # test default ping setup
+        status, message = self.ptool.setupPing(context=obj)
+        self.failUnless(status=='success')
+        self.failUnless(message=='Your changes have been saved')
+        syInfo = getattr(obj, 'syndication_information', None)
+        self.failUnless(syInfo.ping_sites==[])
+        self.failUnless(syInfo.enable_ping==0)
+        
+        # test ping setup with disable syndication and ping
+        self.b1.disableSyndication()
+        status, message = self.ptool.setupPing(context=obj, enable_ping=0, ping_sites=('http://nohost',), REQUEST=None)
+        self.failUnless(status=='failed')
+        self.failUnless(message=='Syndication is Disabled')
+        syInfo = getattr(obj, 'syndication_information', None)
+        self.failUnless(syInfo is None)
+        
+        # test ping setup with enable syndication and ping
+        self.b1.enableSyndication()
+        status, message = self.ptool.setupPing(context=obj, enable_ping=1, ping_sites=('http://nohost',), REQUEST=None)
+        self.failUnless(status=='success')
+        self.failUnless(message=='Your changes have been saved')
+        syInfo = getattr(obj, 'syndication_information', None)
+        self.failUnless(syInfo.ping_sites==['http://nohost'])
+        self.failUnless(syInfo.enable_ping==1)
+
+    def testGetPingProperties(self):
+        obj = self.b1
+        syInfo = getattr(obj, 'syndication_information', None)
+        syInfo.ping_sites = ('http://nohost/1', 'http://nohost/2')
+        syInfo.enable_ping = 1
+        dic = self.ptool.getPingProperties(obj)
+        self.failUnless(tuple(dic['ping_sites'])==('http://nohost/1','http://nohost/2'))
+        self.failUnless(dic['enable_ping']==1)
+
+    def testPingFeedReader(self):
+        obj = self.b1
+
+        # test with default properties
+        status, message = self.ptool.pingFeedReader(obj)
+        self.failUnless(status=='failed')
+        self.failUnless(message=='Ping is dissabled.')
+
+        # test with customized properties
+        self.ptool.invokeFactory(id = 'testsite', type_name = "PingInfo", title = 'www.TESTSITE.com (blog url)', url = 'http://nohost/')
+        self.ptool.setupPing(context=obj, enable_ping=1, ping_sites=('testsite',))
+
+        status, message = self.ptool.pingFeedReader(obj)
+        self.failUnless(status=='success')
+        self.failUnless(message=='The servers are pinged.\nReturned message: The site http://nohost/ generated error for plone/b1.')
+
+def test_suite():
+    from unittest import TestSuite, makeSuite
+    suite = TestSuite()
+    suite.addTest(makeSuite(TestPingTool))
+    return suite
+
+if __name__ == '__main__':
+    framework()
+
Index: ingTool/branches/plone-3.1/util.py
===================================================================
--- /qPingTool/branches/plone-3.1/util.py	(revision 185)
+++ 	(revision )
@@ -1,13 +1,0 @@
-from Products.CMFCore.utils import getToolByName
-
-def getCanonicalURL(context):
-    """ Uniform method for get portal canonical url."""
-    p_url = getToolByName(context, 'portal_url')
-    canonical_url = ""
-    try:
-        from adapter import ICanonicalURL
-        canonical_url = ICanonicalURL(p_url).getCanonicalURL()
-    except:
-        canonical_url = p_url.getCanonicalURL()
-
-    return canonical_url
