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

Last change on this file since 1817 was 1817, checked in by mylan, 14 years ago

#142: Fix access of of seo_context view by viewlets. Little optimization of TitleCommentViewlet?

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