[1052] | 1 | from cgi import escape |
---|
[387] | 2 | from zope.component import getMultiAdapter |
---|
| 3 | from zope.viewlet.interfaces import IViewlet |
---|
| 4 | from Products.CMFPlone.utils import safe_unicode |
---|
| 5 | from plone.app.layout.viewlets.common import ViewletBase |
---|
| 6 | from Products.CMFCore.utils import getToolByName |
---|
| 7 | from AccessControl import Unauthorized |
---|
| 8 | from quintagroup.seoptimizer.util import SortedDict |
---|
| 9 | from quintagroup.seoptimizer.interfaces import IKeywords |
---|
| 10 | |
---|
| 11 | class TitleCommentViewlet(ViewletBase): |
---|
| 12 | |
---|
| 13 | def update(self): |
---|
| 14 | self.portal_state = getMultiAdapter((self.context, self.request), |
---|
| 15 | name=u'plone_portal_state') |
---|
| 16 | self.context_state = getMultiAdapter((self.context, self.request), |
---|
| 17 | name=u'plone_context_state') |
---|
| 18 | self.page_title = self.context_state.object_title |
---|
| 19 | self.portal_title = self.portal_state.portal_title |
---|
| 20 | |
---|
| 21 | self.override_title = self.context.hasProperty('qSEO_title') |
---|
| 22 | self.override_comments = self.context.hasProperty('qSEO_html_comment') |
---|
| 23 | |
---|
[1052] | 24 | def std_title(self): |
---|
| 25 | portal_title = safe_unicode(self.portal_title()) |
---|
| 26 | page_title = safe_unicode(self.page_title()) |
---|
| 27 | if page_title == portal_title: |
---|
| 28 | return u"<title>%s</title>" % (escape(portal_title)) |
---|
| 29 | else: |
---|
| 30 | return u"<title>%s — %s</title>" % ( |
---|
| 31 | escape(safe_unicode(page_title)), |
---|
| 32 | escape(safe_unicode(portal_title))) |
---|
| 33 | |
---|
[387] | 34 | def render(self): |
---|
[1052] | 35 | std_title = self.std_title() |
---|
[413] | 36 | seo_context = getMultiAdapter((self.context, self.request), name='seo_context') |
---|
[387] | 37 | if not self.override_title: |
---|
| 38 | if not self.override_comments: |
---|
| 39 | return std_title |
---|
| 40 | else: |
---|
[413] | 41 | qseo_comments = u"<!--%s-->"%safe_unicode(seo_context.seo_html_comment()) |
---|
[387] | 42 | return u"%s\n%s"%(std_title, qseo_comments) |
---|
| 43 | else: |
---|
[413] | 44 | qseo_title = u"<title>%s</title>" % safe_unicode(seo_context.seo_title()) |
---|
[387] | 45 | if not self.override_comments: |
---|
| 46 | return qseo_title |
---|
| 47 | else: |
---|
[413] | 48 | qseo_comments = u"<!--%s-->"%safe_unicode(seo_context.seo_html_comment()) |
---|
[387] | 49 | return u"%s\n%s"%(qseo_title, qseo_comments) |
---|
| 50 | |
---|
| 51 | class HTTPEquiv(ViewletBase): |
---|
| 52 | |
---|
| 53 | def charset( self ): |
---|
| 54 | context = self.context.aq_inner |
---|
| 55 | site_properties = getToolByName( context, 'portal_properties').site_properties |
---|
| 56 | return site_properties.getProperty('default_charset', 'utf-8') |
---|
[404] | 57 | |
---|
| 58 | def render( self ): |
---|
| 59 | return """<meta http-equiv="Content-Type" content="text/html; charset=%s" />"""%self.charset() |
---|
[387] | 60 | |
---|
| 61 | class BaseUrlViewlet( ViewletBase ): |
---|
| 62 | """ |
---|
| 63 | simpel viewlet for base href rendering |
---|
| 64 | """ |
---|
| 65 | def renderBase( self ): |
---|
| 66 | # returns correct base href |
---|
| 67 | context = self.context.aq_inner |
---|
| 68 | isFolder = getattr(context.aq_explicit, 'isPrincipiaFolderish', 0) |
---|
| 69 | base_url = context.absolute_url() |
---|
| 70 | |
---|
| 71 | # when accessing via WEBDAV you're not allowed to access aq_explicit |
---|
| 72 | try: |
---|
[957] | 73 | return isFolder and '%s/'%base_url or base_url |
---|
[387] | 74 | except (Unauthorized, 'Unauthorized'): |
---|
| 75 | pass |
---|
| 76 | |
---|
| 77 | def render( self ): |
---|
| 78 | return """<base href="%s" /><!--[if lt IE 7]></base><![endif]-->"""% self.renderBase() |
---|
| 79 | |
---|
| 80 | class MetaTagsViewlet( ViewletBase ): |
---|
| 81 | |
---|
| 82 | def listMetaTags( self ): |
---|
| 83 | context = self.context.aq_inner |
---|
| 84 | portal_props = getToolByName(context, 'portal_properties') |
---|
| 85 | pu = getToolByName(context, 'plone_utils') |
---|
| 86 | seo_props = getToolByName(portal_props, 'seo_properties', None) |
---|
| 87 | if seo_props is None: |
---|
| 88 | return pu.listMetaTags(context) |
---|
| 89 | |
---|
| 90 | site_props = getToolByName(portal_props, 'site_properties') |
---|
| 91 | exposeDCMetaTags = site_props.exposeDCMetaTags |
---|
| 92 | |
---|
| 93 | metaTags = SortedDict() |
---|
| 94 | metaTags.update(pu.listMetaTags(context)) |
---|
| 95 | metadataList = [ |
---|
[424] | 96 | ('seo_description', 'description'), |
---|
| 97 | ('seo_keywords', 'keywords'), |
---|
| 98 | ('seo_robots', 'robots'), |
---|
| 99 | ('seo_distribution','distribution')] |
---|
[387] | 100 | |
---|
| 101 | if exposeDCMetaTags: |
---|
| 102 | metadataList.append(('qSEO_Distribution', 'DC.distribution')) |
---|
| 103 | |
---|
[424] | 104 | seo_context = getMultiAdapter((self.context, self.request), name='seo_context') |
---|
[387] | 105 | for accessor, key in metadataList: |
---|
[424] | 106 | method = getattr(seo_context, accessor, None) |
---|
[387] | 107 | if not callable(method): |
---|
| 108 | # ups |
---|
| 109 | continue |
---|
| 110 | # Catch AttributeErrors raised by some AT applications |
---|
| 111 | try: |
---|
| 112 | value = method() |
---|
| 113 | except AttributeError: |
---|
| 114 | value = None |
---|
| 115 | |
---|
| 116 | if not value: |
---|
| 117 | continue |
---|
| 118 | if isinstance(value, (tuple, list)): |
---|
| 119 | value = ', '.join(value) |
---|
| 120 | |
---|
| 121 | metaTags[key] = value |
---|
| 122 | |
---|
[1261] | 123 | # add custom meta tags (added from qseo tab by user) for given context and default from configlet |
---|
| 124 | custom_meta_tags = seo_context.seo_customMetaTags() |
---|
| 125 | for tag in custom_meta_tags: |
---|
[1265] | 126 | if tag['meta_content']: |
---|
| 127 | metaTags[tag['meta_name']] = tag['meta_content'] |
---|
[387] | 128 | |
---|
| 129 | # Set the additional matching keywords, if any |
---|
| 130 | adapter = IKeywords(context, None) |
---|
| 131 | if adapter is not None: |
---|
| 132 | keywords = adapter.listKeywords() |
---|
| 133 | if keywords: |
---|
| 134 | metaTags['keywords'] = keywords |
---|
| 135 | |
---|
[404] | 136 | return metaTags |
---|
[387] | 137 | |
---|
[404] | 138 | def render( self ): |
---|
[562] | 139 | return '\n'.join([safe_unicode("""<meta name="%s" content="%s" />"""%(name, content)) \ |
---|
| 140 | for name, content in self.listMetaTags().items()]) |
---|
[404] | 141 | |
---|
[869] | 142 | class CustomScriptViewlet( ViewletBase ): |
---|
| 143 | |
---|
| 144 | def getCustomScript( self ): |
---|
| 145 | context = self.context.aq_inner |
---|
| 146 | portal_props = getToolByName(context, 'portal_properties') |
---|
| 147 | seo_props = getToolByName(portal_props, 'seo_properties', None) |
---|
| 148 | if seo_props is None: |
---|
| 149 | return '' |
---|
| 150 | return seo_props.getProperty('custom_script', '') |
---|
| 151 | |
---|
| 152 | def render( self ): |
---|
| 153 | return safe_unicode("""%s"""% self.getCustomScript()) |
---|
| 154 | |
---|
[896] | 155 | |
---|
| 156 | class CanonicalUrlViewlet( ViewletBase ): |
---|
| 157 | """ |
---|
| 158 | simple viewlet for canonical url link rendering |
---|
| 159 | """ |
---|
| 160 | |
---|
| 161 | def render( self ): |
---|
| 162 | seo_context = getMultiAdapter((self.context, self.request), name='seo_context') |
---|
| 163 | return """<link rel="canonical" href="%s" />""" % seo_context.seo_canonical() |
---|
| 164 | |
---|