Index: /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/browser/viewlets.py
===================================================================
--- /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/browser/viewlets.py	(revision 1930)
+++ /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/browser/viewlets.py	(revision 1931)
@@ -206,6 +206,5 @@
     """ Simple viewlet for canonical url link rendering.
     """
-
     def render( self ):
-        seo_context = getMultiAdapter((self.context, self.request), name='seo_context')
-        return """<link rel="canonical" href="%s" />""" % seo_context['seo_canonical']
+        seoc = getMultiAdapter((self.context, self.request), name=u'seo_context')
+        return """<link rel="canonical" href="%s" />""" % seoc['seo_canonical']
Index: /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/browser/views.py
===================================================================
--- /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/browser/views.py	(revision 1930)
+++ /quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/browser/views.py	(revision 1931)
@@ -13,4 +13,7 @@
 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
 from Products.CMFPlone import PloneMessageFactory as pmf
+
+from quintagroup.canonicalpath.interfaces import ICanonicalLink
+from quintagroup.canonicalpath.adapters import PROPERTY_LINK as CANONICAL_PROPERTY
 
 from quintagroup.seoptimizer import interfaces
@@ -55,5 +58,5 @@
             "meta_keywords": self.getSEOProperty('qSEO_keywords', 'Subject', ()),
             "seo_keywords": self.getSEOProperty('qSEO_keywords', default=()),
-            "seo_canonical": self.seo_canonical(),
+            "seo_canonical": ICanonicalLink(self.context).canonical_link,
             # Add test properties
             "has_seo_title": self.context.hasProperty('qSEO_title'),
@@ -63,5 +66,5 @@
             "has_html_comment": self.context.hasProperty('qSEO_html_comment'),
             "has_seo_keywords": self.context.hasProperty('qSEO_keywords'),
-            "has_seo_canonical": self.context.hasProperty('qSEO_canonical'),
+            "has_seo_canonical": self.context.hasProperty(CANONICAL_PROPERTY),
             }
         #seotags["seo_nonEmptylocalMetaTags"] = bool(seotags["seo_localCustomMetaTags"])
@@ -135,10 +138,4 @@
         return result
 
-    def seo_canonical( self ):
-        """ Generate canonical URL from SEO properties.
-        """
-        canpath = queryAdapter(self.context, interfaces.ISEOCanonicalPath)
-        return self.pps.portal_url() + canpath.canonical_path()
-
 
 class SEOContextPropertiesView( BrowserView ):
@@ -159,23 +156,8 @@
         return condition and first or second 
 
-    def getMainDomain(self, url):
-        """ Get a main domain.
-        """
-        url = url.split('//')[-1]
-        dompath = url.split(':')[0]
-        dom = dompath.split('/')[0]
-        return '.'.join(dom.split('.')[-2:])
-
     def validateSEOProperty(self, property, value):
         """ Validate a seo property.
         """
-        purl = getToolByName(self.context, 'portal_url')()
-        state = ''
-        if property == PROP_PREFIX+'canonical':
-            # validate seo canonical url property
-            pdomain = self.getMainDomain(purl)
-            if not pdomain == self.getMainDomain(value):
-                state = _('canonical_msg', default=u'Canonical URL mast be in ${pdomain} domain.', mapping={'pdomain': pdomain})
-        return state
+        return ''
 
     def setProperty(self, property, value, type='string'):
@@ -208,4 +190,10 @@
             if seo_key == 'custommetatags':
                 self.manageSEOCustomMetaTagsProperties(**kw)
+            elif seo_key == 'canonical':
+                canonical = seo_items[seo_key]
+                try:
+                    ICanonicalLink(self.context).canonical_link = canonical
+                except InvalidValue, e:
+                    return str(e)
             else:
                 if seo_key in seo_overrides_keys and seo_items.get(seo_key+SUFFIX):
