source: products/quintagroup.seoptimizer/trunk/quintagroup/seoptimizer/browser/views.py @ 1463

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

refactor seo_context_properties cpy script to browser view

  • Property svn:eol-style set to native
File size: 13.7 KB
Line 
1from Acquisition import aq_inner
2from zope.component import queryAdapter
3from plone.app.controlpanel.form import ControlPanelView
4
5from Products.Five.browser import BrowserView
6from Products.CMFCore.utils import getToolByName
7from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
8
9from quintagroup.seoptimizer import SeoptimizerMessageFactory as _
10
11SEPERATOR = '|'
12HAS_CANONICAL_PATH = True
13SEO_PREFIX = 'seo_'
14PROP_PREFIX = 'qSEO_'
15SUFFIX = '_override'
16PROP_CUSTOM_PREFIX = 'qSEO_custom_'
17
18try:
19    from quintagroup.canonicalpath.interfaces import ICanonicalPath
20except ImportError:
21    HAS_CANONICAL_PATH = False
22
23class SEOContext( BrowserView ):
24    """
25    """
26    def getSEOProperty( self, property_name, accessor='' ):
27        """
28        """
29        context = aq_inner(self.context)
30
31        if context.hasProperty(property_name):
32            return context.getProperty(property_name)
33       
34        if accessor:
35            method = getattr(context, accessor, None)
36            if not callable(method):
37                return None
38
39            # Catch AttributeErrors raised by some AT applications
40            try:
41                value = method()
42            except AttributeError:
43                value = None
44       
45            return value
46
47    def seo_title( self ):
48        """
49        """
50        return self.getSEOProperty( 'qSEO_title', accessor='Title' )
51
52    def seo_robots( self ):
53        """
54        """
55        robots = self.getSEOProperty( 'qSEO_robots' )
56        return robots and robots or 'ALL'
57
58    def seo_description( self ):
59        """
60            Generate Description from SEO properties
61        """
62       
63        return self.getSEOProperty( 'qSEO_description', accessor = 'Description')
64
65    def seo_distribution( self ):
66        """
67           Generate Description from SEO properties
68        """
69        dist = self.getSEOProperty( 'qSEO_distribution' )
70
71        return dist and dist or 'Global'
72
73    def seo_customMetaTags( self ):
74        """
75        """
76        tags = self.seo_globalCustomMetaTags()
77        loc = self.seo_localCustomMetaTags()
78
79        names = [i['meta_name'] for i in tags]
80        add_tags = []
81        for i in loc:
82            if i['meta_name'] in names:
83                for t in tags:
84                    if t['meta_name'] == i['meta_name']:
85                        t['meta_content'] = i['meta_content']
86            else:
87                add_tags.append(i)
88        tags.extend(add_tags)
89        return tags
90
91    def seo_globalWithoutLocalCustomMetaTags( self ):
92        """
93        """
94        glob = self.seo_globalCustomMetaTags()
95        loc = self.seo_localCustomMetaTags()
96        names = [i['meta_name'] for i in loc]
97        tags = []
98        for i in glob:
99            if i['meta_name'] not in names:
100                tags.append(i)
101        return tags
102
103    def seo_localCustomMetaTags( self ):
104        """
105        """
106        result = []
107        property_prefix = 'qSEO_custom_'
108        context = aq_inner(self.context)
109        for property, value in context.propertyItems():
110            if property.startswith(property_prefix) and property[len(property_prefix):]:
111                result.append({'meta_name'    : property[len(property_prefix):],
112                               'meta_content' : value})
113        return result
114
115    def seo_globalCustomMetaTags( self ):
116        """
117        """
118        result = []
119        context = aq_inner(self.context)
120        site_properties = getToolByName(context, 'portal_properties')
121        if hasattr(site_properties, 'seo_properties'):
122            custom_meta_tags = getattr(site_properties.seo_properties, 'default_custom_metatags', [])
123            for tag in custom_meta_tags:
124                name_value = tag.split(SEPERATOR)
125                if name_value[0]:
126                    result.append({'meta_name'    : name_value[0],
127                                   'meta_content' : len(name_value) == 2 and name_value[1] or ''})
128        return result
129
130    def seo_nonEmptylocalMetaTags( self ):
131        """
132        """
133        return bool(self.seo_localCustomMetaTags())
134
135    def seo_html_comment( self ):
136        """
137        """
138        html_comment = self.getSEOProperty( 'qSEO_html_comment' )
139        return html_comment and html_comment or '' 
140       
141    def seo_keywords( self ):
142        """
143           Generate Keywords from SEO properties
144        """
145
146        prop_name = 'qSEO_keywords'
147        add_keywords = 'additional_keywords'
148        accessor = 'Subject'
149        context = aq_inner(self.context)
150
151        keywords = []
152        if context.hasProperty(prop_name):
153            keywords = context.getProperty(prop_name)
154
155        pprops = getToolByName(context, 'portal_properties')
156        sheet = getattr(pprops, 'seo_properties', None)
157        if sheet and sheet.hasProperty(add_keywords):
158            keywords += sheet.getProperty(add_keywords)
159
160        if keywords:
161            return keywords
162
163        method = getattr(context, accessor, None)
164        if not callable(method):
165            return None
166
167        # Catch AttributeErrors raised by some AT applications
168        try:
169            value = method()
170        except AttributeError:
171            value = None
172
173        return value
174   
175    def seo_canonical( self ):
176        """
177           Get canonical URL
178        """
179        canonical = self.getSEOProperty( 'qSEO_canonical' )
180
181        if not canonical and HAS_CANONICAL_PATH:
182            canpath = queryAdapter(self.context, ICanonicalPath)
183            if canpath:
184                purl = getToolByName(self.context, 'portal_url')()
185                cpath = canpath.canonical_path()
186                canonical = purl + cpath
187
188        return canonical and canonical or self.context.absolute_url()
189
190
191class SEOControlPanel( ControlPanelView ):
192    """
193    """
194    template = ViewPageTemplateFile('templates/seo_controlpanel.pt')
195
196    @property
197    def portal_properties( self ):
198        """
199        """
200        context = aq_inner(self.context)
201        return getToolByName(context, 'portal_properties')
202
203    @property
204    def portal_types( self ):
205        """
206        """
207        context = aq_inner(self.context)
208        return getToolByName(context, 'portal_types')
209
210    def hasSEOAction( self, type_info ):
211        """
212        """
213        return filter(lambda x:x.id == 'seo_properties', type_info.listActions())
214
215    def test( self, condition, first, second ):
216        """
217        """
218        return condition and first or second
219
220    def getExposeDCMetaTags( self ):
221        """
222        """
223        sp = self.portal_properties.site_properties
224        return sp.getProperty('exposeDCMetaTags')
225
226    def getDefaultCustomMetatags( self ):
227        """
228        """
229        seo = self.portal_properties.seo_properties
230        return seo.getProperty('default_custom_metatags')
231
232    def getMetaTagsOrder( self ):
233        """
234        """
235        seo = self.portal_properties.seo_properties
236        return seo.getProperty('metatags_order')
237
238    def getAdditionalKeywords( self ):
239        """
240        """
241        seo = self.portal_properties.seo_properties
242        return seo.getProperty('additional_keywords')
243
244    def createMultiColumnList( self ):
245        """
246        """
247        context = aq_inner(self.context)
248        allTypes = self.portal_types.listContentTypes()
249        try:
250            return context.createMultiColumnList(allTypes, sort_on='title_or_id')
251        except AttributeError:
252            return [slist]
253
254    def __call__( self ):
255        """
256        """
257        context = aq_inner(self.context)
258        request = self.request
259
260        portalTypes=request.get( 'portalTypes', [] )
261        exposeDCMetaTags=request.get( 'exposeDCMetaTags', None )
262        additionalKeywords=request.get('additionalKeywords', [])
263        default_custom_metatags=request.get('default_custom_metatags', [])
264        metatags_order=request.get('metatags_order', [])
265
266        site_props = getToolByName(self.portal_properties, 'site_properties')
267        seo_props = getToolByName(self.portal_properties, 'seo_properties')
268
269        form = self.request.form
270        submitted = form.get('form.submitted', False)
271
272        if submitted:
273            site_props.manage_changeProperties(exposeDCMetaTags=exposeDCMetaTags)
274            seo_props.manage_changeProperties(additional_keywords=additionalKeywords)
275            seo_props.manage_changeProperties(default_custom_metatags=default_custom_metatags)
276            seo_props.manage_changeProperties(metatags_order=metatags_order)
277
278            for ptype in self.portal_types.objectValues():
279                acts = filter(lambda x: x.id == 'seo_properties', ptype.listActions())
280                action = acts and acts[0] or None
281                if ptype.getId() in portalTypes:
282                    if action is None:
283                        ptype.addAction('seo_properties',
284                                        'SEO Properties',
285                                        'string:${object_url}/@@seo-context-properties',
286                                        '',
287                                        'Modify portal content',
288                                        'object',
289                                        visible=1)
290                else:
291                    if action !=None:
292                        actions = list(ptype.listActions())
293                        ptype.deleteActions([actions.index(a) for a in actions if a.getId()=='seo_properties'])
294            return request.response.redirect('%s/%s'%(self.context.absolute_url(), '@@seo-controlpanel'))
295        else:
296            return self.template(portalTypes=portalTypes, exposeDCMetaTags=exposeDCMetaTags)
297
298    def typeInfo( self, type_name ):
299        """
300        """
301        return self.portal_types.getTypeInfo( type_name )
302
303
304class SEOContextPropertiesView( BrowserView ):
305    """
306    """
307    template = ViewPageTemplateFile('templates/seo_context_properties.pt')
308
309
310    def test( self, condition, first, second ):
311        """
312        """
313        return condition and first or second
314     
315    def setProperty(self, property, value, type='string'):
316        context = aq_inner(self.context)
317        if context.hasProperty(property):
318            context.manage_changeProperties({property: value})
319        else:
320            context.manage_addProperty(property, value, type)
321
322    def manageSEOProps(self, **kw):
323        context = aq_inner(self.context)
324        delete_list, overrides, values = [], [], []
325        seo_items = dict([(k[len(SEO_PREFIX):],v) for k,v in kw.items() if k.startswith(SEO_PREFIX)])
326        for key in seo_items.keys():
327            if key.endswith(SUFFIX):
328                overrides.append(key[:-len(SUFFIX)])
329            else:
330                values.append(key)
331
332        for val in values:
333            if val in overrides and seo_items[val+SUFFIX]:
334                self.setProperty(PROP_PREFIX+val, seo_items[val])
335            elif context.hasProperty(PROP_PREFIX+val):
336                delete_list.append(PROP_PREFIX+val)
337        if delete_list: context.manage_delProperties(delete_list)
338
339    def setSEOCustomMetaTags(self, custommetatags):
340        context = aq_inner(self.context)
341        for tag in custommetatags:
342            self.setProperty('%s%s' % (PROP_CUSTOM_PREFIX, tag['meta_name']), tag['meta_content'])
343
344    def delAllSEOCustomMetaTagsByNames(self):
345        context = self.context
346        delete_list = []
347        for property, value in context.propertyItems():
348            if property.find(PROP_CUSTOM_PREFIX) == 0 and len(property) > len(PROP_CUSTOM_PREFIX):
349                delete_list.append(property)
350        if delete_list: context.manage_delProperties(delete_list)       
351
352    def delSEOCustomMetaTagByName(self, custommetatagname):
353        context = self.context
354        seo_custom_prop = PROP_CUSTOM_PREFIX + custommetatagname
355        if context.hasProperty(seo_custom_prop):
356            context.manage_delProperties([seo_custom__prop])
357
358    def updateSEOCustomMetaTags(self, custommetatags):
359        context = aq_inner(self.context)
360        site_properties = getToolByName(context, 'portal_properties')
361        globalCustomMetaTags = []
362
363        if hasattr(site_properties, 'seo_properties'):
364            custom_meta_tags = getattr(site_properties.seo_properties, 'default_custom_metatags', [])
365            for tag in custom_meta_tags:
366                name_value = tag.split(SEPERATOR)
367                if name_value[0]:
368                    globalCustomMetaTags.append({'meta_name'    : name_value[0],
369                                                 'meta_content' : len(name_value) == 1 and '' or name_value[1]})
370        metalist = []
371        for tag in custommetatags:
372            meta_name, meta_content = tag['meta_name'], tag['meta_content']
373            if meta_name:
374                if not [gmt for gmt in globalCustomMetaTags if (gmt['meta_name']==meta_name and gmt['meta_content']==meta_content)]:
375                    metalist.append(tag)
376        if metalist: self.setSEOCustomMetaTags(metalist)
377     
378    def manageSEOCustomMetaTags(self, **kw):
379        context = aq_inner(self.context)
380        if kw.has_key('seo_custommetatags_override'):
381            if kw.get('seo_custommetatags_override'):
382                custommetatags = kw.get('seo_custommetatags', {})
383                self.updateSEOCustomMetaTags(custommetatags)
384            else:
385                self.delAllSEOCustomMetaTagsByNames()
386        elif kw.get('seo_custommetatags'):
387            self.delAllSEOCustomMetaTagsByNames()
388
389    def __call__( self ):
390        """
391        """
392        context = aq_inner(self.context)
393        request = self.request
394        form = self.request.form
395        submitted = form.get('form.submitted', False)
396        if submitted:
397            self.manageSEOProps(**form)
398            self.manageSEOCustomMetaTags(**form)
399            context.plone_utils.addPortalMessage( _(u'Content SEO properties have been saved.'))
400            return request.response.redirect(self.context.absolute_url())
401        else:
402            return self.template()
Note: See TracBrowser for help on using the repository browser.