source: products/quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/browser/viewlets.py @ 1958

Last change on this file since 1958 was 1958, checked in by liebster, 14 years ago

Clean-up code http://codereview.corp.quintagroup.com/40241/show

  • Property svn:eol-style set to native
File size: 7.9 KB
Line 
1from cgi import escape
2from DateTime import DateTime
3from Acquisition import aq_inner
4
5from zope.component import queryAdapter
6from zope.component import queryMultiAdapter
7from zope.component import getMultiAdapter
8from plone.app.layout.viewlets.common import ViewletBase
9
10from Products.CMFPlone.utils import safe_unicode, getSiteEncoding
11
12from quintagroup.seoptimizer.util import SortedDict
13from quintagroup.seoptimizer.interfaces import IMetaKeywords
14from quintagroup.seoptimizer.interfaces import IMappingMetaTags
15from quintagroup.seoptimizer.browser.seo_configlet import ISEOConfigletSchema
16
17from Products.CMFPlone.PloneTool import *
18
19class SEOTagsViewlet( ViewletBase ):
20    """ Simple viewlet for custom title rendering.
21    """
22
23    def render(self):
24        TEMPLATE = '<meta name="%s" content="%s"/>'
25        enc = getSiteEncoding(self.context)
26        sfuncd = lambda x, enc=enc:safe_unicode(x, enc)
27        return u'\n'.join([TEMPLATE % tuple(map(sfuncd, (k,v))) \
28                           for k,v in self.listMetaTags().items()])
29
30    def listMetaTags(self):
31        """Calculate list metatags"""
32
33        result = SortedDict()
34        pps = queryMultiAdapter((self.context, self.request), name="plone_portal_state")
35        seo_global = queryAdapter(pps.portal(), ISEOConfigletSchema)
36        seo_context = queryMultiAdapter((self.context, self.request), name='seo_context')
37
38        use_all = seo_global.exposeDCMetaTags
39        adapter = IMappingMetaTags(self.context, None)
40        mapping_metadata = adapter and adapter.getMappingMetaTags() or SortedDict()
41
42        if not use_all:
43            metadata_names = mapping_metadata.has_key('DC.description') \
44                             and {'DC.description': mapping_metadata['DC.description']} \
45                             or SortedDict()
46            if mapping_metadata.has_key('description'):
47                metadata_names['description'] = mapping_metadata['description']
48        else:
49            metadata_names = mapping_metadata
50
51        for key, accessor in metadata_names.items():
52            if accessor == 'meta_keywords':
53                # Render all the existing keywords for the current content type
54                adapter = IMetaKeywords(self.context, None)
55                if adapter is not None:
56                    keywords = adapter.getMetaKeywords()
57                    if keywords:
58                        result['keywords'] = keywords
59                continue
60
61            if seo_context._seotags.has_key(accessor):
62                value = seo_context._seotags.get(accessor, None)
63            else:
64                method = getattr(seo_context, accessor, None)
65                if method is None:
66                    method = getattr(aq_inner(self.context).aq_explicit, accessor, None)
67
68                if not callable(method):
69                    continue
70
71                # Catch AttributeErrors raised by some AT applications
72                try:
73                    value = method()
74                except AttributeError:
75                    value = None
76
77            if not value:
78                # No data
79                continue
80            if accessor == 'Publisher' and value == 'No publisher':
81                # No publisher is hardcoded (TODO: still?)
82                continue
83            if isinstance(value, (list, tuple)):
84                # convert a list to a string
85                value = ', '.join(value)
86
87            # Special cases
88            if accessor == 'Description' and not metadata_names.has_key('description'):
89                result['description'] = value
90            elif accessor == 'Subject' and not metadata_names.has_key('keywords'):
91                result['keywords'] = value
92
93            if accessor not in ('Description', 'Subject'):
94                result[key] = value
95
96        if use_all:
97            created = self.context.CreationDate()
98
99            try:
100                effective = self.context.EffectiveDate()
101                if effective == 'None':
102                    effective = None
103                if effective:
104                    effective = DateTime(effective)
105            except AttributeError:
106                effective = None
107
108            try:
109                expires = self.context.ExpirationDate()
110                if expires == 'None':
111                    expires = None
112                if expires:
113                    expires = DateTime(expires)
114            except AttributeError:
115                expires = None
116
117            # Filter out DWIMish artifacts on effective / expiration dates
118            if effective is not None and \
119               effective > FLOOR_DATE and \
120               effective != created:
121                eff_str = effective.Date()
122            else:
123                eff_str = ''
124
125            if expires is not None and expires < CEILING_DATE:
126                exp_str = expires.Date()
127            else:
128                exp_str = ''
129
130            if exp_str or exp_str:
131                result['DC.date.valid_range'] = '%s - %s' % (eff_str, exp_str)
132
133        # add custom meta tags (added from qseo tab by user)
134        # for given context and default from configlet
135        custom_meta_tags = seo_context and seo_context['seo_customMetaTags'] or []
136        for tag in custom_meta_tags:
137            if tag['meta_content']:
138                result[tag['meta_name']] = tag['meta_content']
139
140        return result
141
142
143
144class TitleCommentViewlet(ViewletBase):
145    """ Simple viewlet for custom title rendering.
146    """
147
148    def update(self):
149        self.portal_state = getMultiAdapter((self.context, self.request),
150                                            name=u'plone_portal_state')
151        self.context_state = getMultiAdapter((self.context, self.request),
152                                             name=u'plone_context_state')
153        self.seo_context = getMultiAdapter((self.context, self.request),
154                                             name=u'seo_context')
155
156        self.override_title = self.seo_context['has_seo_title']
157        self.override_comments = self.seo_context['has_html_comment']
158
159    def std_title(self):
160        portal_title = safe_unicode(self.context_state.object_title())
161        page_title = safe_unicode(self.portal_state.portal_title())
162        if page_title == portal_title:
163            return u"<title>%s</title>" % (escape(portal_title))
164        else:
165            return u"<title>%s &mdash; %s</title>" % (
166                escape(safe_unicode(page_title)),
167                escape(safe_unicode(portal_title)))
168
169    def render(self):
170        if not self.override_title:
171            std_title = self.std_title()
172            if not self.override_comments:
173                return std_title
174            else:
175                qseo_comments = u"<!--%s-->" % safe_unicode(
176                    self.seo_context["seo_html_comment"])
177                return u"%s\n%s"%(std_title, qseo_comments)
178        else:
179            qseo_title = u"<title>%s</title>" % safe_unicode(
180                self.seo_context["seo_title"])
181            if not self.override_comments:
182                return qseo_title
183            else:
184                qseo_comments = u"<!--%s-->" % safe_unicode(
185                    self.seo_context["seo_html_comment"])
186                return u"%s\n%s"%(qseo_title, qseo_comments)
187
188
189class CustomScriptViewlet( ViewletBase ):
190    """ Simple viewlet for custom script rendering.
191    """
192    def getCustomScript( self ):
193        pps = queryMultiAdapter((self.context, self.request),
194                                name="plone_portal_state")
195        gseo = queryAdapter(pps.portal(), ISEOConfigletSchema)
196        if gseo:
197            return gseo.custom_script
198        return ''
199
200    def render( self ):
201        return safe_unicode("""%s"""% self.getCustomScript())
202
203
204class CanonicalUrlViewlet( ViewletBase ):
205    """ Simple viewlet for canonical url link rendering.
206    """
207    def render( self ):
208        seoc = getMultiAdapter((self.context, self.request), name=u'seo_context')
209        return """<link rel="canonical" href="%s" />""" % seoc['seo_canonical']
Note: See TracBrowser for help on using the repository browser.